8

我期待代码

foo=proc{puts "foo"}

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

输出

1
2
3
富
酒吧

但是得到了错误

块 arg 和给定的实际块

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

4

2 回答 2

5

&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)

并得到相同的结果。

更多信息在 Ruby 中 block 和 &block 之间的区别

于 2013-03-12T09:40:17.137 回答
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而不是在内屈服,您将得到 LocalJumpError inner_block.call,我不完全确定为什么。如果有人有这个答案,那么我会很感兴趣。

于 2016-11-17T22:55:26.783 回答