我可以将一个本身期望块​​的块传递给ruby中的instance_exec吗?

时间:2013-03-12 09:05:26

标签: ruby block proc

我希望代码

foo=proc{puts "foo"}

instance_exec(1,2,3,&foo) do |*args , &block|
  puts *args
  block.call
  puts "bar"
end

输出

1
2
3
foo
bar

但得到了错误

both block arg and actual block given

我可以将一个本身期望块​​的块传递给ruby中的instance_exec吗?

2 个答案:

答案 0 :(得分:4)

&foo尝试将foo作为块传递给instance_exec,并且您已经传递了一个显式块。省略&符号发送foo就像任何其他参数一样(除了它是Proc实例)。所以,试试这个:

instance_exec(1,2,3,foo) do |*args, block|
  puts *args
  block.call
  puts "bar"
end

这也意味着您可以执行以下操作:

bar = proc{ |*args, block|
  puts *args
  block.call
  puts "bar"
}

instance_exec(1,2,3,foo,&bar)

得到相同的结果。

Difference between block and &block in Ruby

的更多信息

答案 1 :(得分:2)

我参加这个派对已经晚了大约3年了,但我想我会分享一种方法,让你更好地对待内部区块,而不仅仅是一个普通的区块。参数。

我知道的最好方法是创建一个对象作为绑定上下文,并将外部块定义为方法。因此,如果我在没有instance_exec调用的情况下重写原始示例,那么......

inner_proc = proc { puts "inner" }
outer_proc = proc { |*args, &inner_block|
  puts *args
  inner_block.call
  puts "bar"
}

我们可以将outer_proc定义为对象的方法

scope_object = Object.new
scope_object.define_singleton_method :bound_proc, &outer_proc

现在,您可以拨打scope_object.bound_proc而不是上面的instance_exec来电。

scope_object.bound_proc 1, 2, 3, &inner_proc

你会得到:

1
2
3
inner
bar

不幸的是,如果你试图在outer_proc内部而不是inner_block.call内部获得一个LocalJumpError,我不完全确定原因。如果有人有这个答案,那么我就会感兴趣。