您不能在方法定义中声明默认块,但是如果没有给出自定义块,您可以使用一个小技巧来使用自定义块。
def say_hello(name)
block = block_given? ? Proc.new : ->(name) { puts "Hi, #{name}" }
block.call(name)
end
# This example uses a custom block
say_hello('weppos') { |name| puts "Hello, #{name}!" }
# => Hello, weppos!
# This example fallbacks to the default
say_hello('weppos')
# => Hi, weppos!
让我稍微解释一下。让我们从更易读的版本开始。
def say_hello(name, &block)
block = block ? block : ->(name) { puts "Hi, #{name}" }
block.call(name)
end
您定义接受块的方法,然后检查是否定义了块。如果没有,您分配一个自定义块。最后,执行块。
让我们稍微增强一下。你可以使用block_given吗?检查一个块是否通过
def say_hello(name, &block)
block = block_given? ? block : ->(name) { puts "Hi, #{name}" }
block.call(name)
end
这也允许您在方法定义中跳过块 (&block) 的声明。
def say_hello(name)
if block_given?
yield name
else
# This is rendundant, but it's for clarity
block = ->(name) { puts "Hi, #{name}" }
block.call(name)
end
end
但是,此时,您也可以使用Proc.new 将块分配给变量。
def say_hello(name)
block = block_given? ? Proc.new : ->(name) { puts "Hi, #{name}" }
block.call(name)
end
最后,我试图了解这种方法何时有意义。在大多数情况下,您可以将代码包装在类或模块中并将其作为参数传递。这可能会更好。