假设我有一个采用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
在库中定义并且猴子修补它不是一个选项。
答案 0 :(得分:2)
为了让ruby明白方法调用中的参数是一个块, commercial和必须放在它前面。
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实例作为最后一个参数传递,并且非常自然地允许在其上调用call
方法。
请注意,将&符号加到方法调用的最后一个参数上强制调用#to_proc
方法,如:
[1,2,3].reduce &:+
#⇒ 6
上面的魔术有效,因为Symbol
类有自己的#to_proc
方法实现。
答案 1 :(得分:0)
你不能在一行中做到(据我所知)。你需要临时变量。
给出这些方法:
def prepare
return [4, proc { puts "called" }]
end
def run(a, &block)
puts a
block.call
end
您可以将prepare
的返回值传递给您的方法,如下所示:
i,blk = prepare()
run(i, &blk)