2013-03-12 8 views
8

私が期待したコードは、私は、それ自体がブロックはRubyでinstance_execことを期待ブロックを渡すことはできますか?

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にブロックを渡すブロックを渡しますか?

答えて

4

&fooは、ブロックとしてfooinstance_execに渡そうとしており、既に明示的なブロックを渡しています。アンパサンドを省略すると、他の引数と同じようにfooが送信されます(ただし、インスタンスはProc)。だから、代わりにこれを試してみてください。

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

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

と同じ結果を得る:

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

また、これはあなたのような何かを行うことができます。私はこのパーティーには約3年遅刻Difference between block and &block in Ruby

+2

残念ながら、これは私の場合は機能しません。私は、実行時間を追跡できるように、既存のprocを透過的にラップしようとしています。私はprocのシグネチャを制御していないので、私はこのメソッドを使うことができません。一般的には、これは良い回避策のようです。 – Ajedi32

2

詳細情報は、私は、私はちょうど平野ではなく、あなたがより多くの本物のブロックのような内部ブロックを処理してみましょうアプローチを共有したいと思いました古い議論。

これについては、バインディング・コンテキストとして機能し、メソッドとして外部ブロックを定義するオブジェクトを作成することが最善の方法です。 instance_execコールせずに次のように私は

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

...元の例を書き換えるのであれば私たちは今、あなたはscope_object.bound_proc代わりのinstance_execコールを呼び出すことができるオブジェクト

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

の方法としてouter_procを定義することができます上記。

scope_object.bound_proc 1, 2, 3, &inner_proc 

あなたは得られます。

1 
2 
3 
inner 
bar 

残念ながら、あなたがLocalJumpErrorを得るでしょうあなたは、むしろinner_block.callより、outer_procの内部で生じるしようとした場合、私はなぜ完全にはよく分かりません。誰かがその答えを持っているなら、私は興味を持っています。

+0

それは動作します!どうもありがとう! – benjaminchanming

関連する問題