假设我有一个采用args和块的方法:
def yield_if_widget(*args, &block)
if args[0].is_a?(Widget)
block.call
end
end
我可以使用参数和块来调用此方法:
yield_if_widget(Widget.new) do
puts "I like widgets"
end
但是如果我有另一个方法来准备参数和块呢?
def widget_and_block
args = [Widget.new]
block = proc{ puts "I like widgets" }
[args, block]
end
我希望能够将它直接传递给第一个方法:
yield_if_widget(*widget_and_block)
这可能吗?怎么样?假设yield_if_widget是在库中定义的并且猴子修补它不是一个选项.
最佳答案 为了让ruby明白方法调用中的参数是一个块,一个商业广告,必须放在它前面.
def widget_and_block
args = [Widget.new]
block = proc{ puts "I like widgets" }
[args, block]
end
wab = widget_and_block
# ⇓
yield_if_widget(*wab.first, &wab.last)
Oneliner(它不会返回yiw返回的内容):
widget_and_block.tap { |args, cb| yield_if_widget *args, &cb }
UPD基本上,方法调用中的&符号用于表示“嘿,将其转换为proc并将其用作代码块”到ruby.它是语言的语法部分,就像你必须将数组内容放在方括号内,而不是卷曲.这就是为什么源代码中应该存在&符号的原因.
另一方面,您是否可以自由修改yield_if_widget并从参数列表中删除&符号:
-def yield_if_widget(*args, &block)
+def yield_if_widget(*args, block)
代码将按预期工作,因为proc实例作为最后一个参数传递,并且很自然地允许调用它.
还请注意,将&符号添加到方法调用的最后一个参数强制在其上调用#to_proc方法,如:
[1,2,3].reduce &:+
#⇒ 6
上面的魔法是有效的,因为Symbol类有它自己的#to_proc方法实现.