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

Posted

技术标签:

【中文标题】我可以将一个本身期望一个块的块传递给 ruby​​ 中的 instance_exec 吗?【英文标题】:Can I pass a block which itself expect a block to instance_exec in ruby? 【发布时间】:2013-02-27 17:15:42 【问题描述】:

我期待代码

foo=procputs "foo"

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

输出

1 2 3 富 酒吧

但是出错了

块 arg 和给定的实际块

【问题讨论】:

【参考方案1】:

&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

【讨论】:

不幸的是,这不适用于我的情况。我正在尝试以一种允许我跟踪其执行时间的方式透明地包装现有的过程。由于我无法控制要包装的 proc 的签名,因此我无法使用此方法。总的来说,这似乎是一个很好的解决方法。【参考方案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,我不完全确定为什么。如果有人有这个答案,那么我会很感兴趣。

【讨论】:

以上是关于我可以将一个本身期望一个块的块传递给 ruby​​ 中的 instance_exec 吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能在 Ruby 中将块传递给 proc?

使用Fiddle将RUBY数组传递给C DLL

ruby 在Ruby中传递块的教训

将 Rust 变量传递给期望能够修改它的 C 函数

如何将类名作为变量传递给ruby中的另一个类

为啥可以将 void(*)(int x, int y) 传递给期望 void(*)() 的 attachInterrupt?