私はコードを期待しています
foo=proc{puts "foo"}
instance_exec(1,2,3,&foo) do |*args , &block|
puts *args
block.call
puts "bar"
end
出力する
1 2 3 foo バー
しかし、エラーが発生しました
ブロック引数と指定された実際のブロックの両方
それ自体がブロックを期待するブロックをrubyのinstance_execに渡すことはできますか?</ p>
&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の違いに関する詳細情報
私はこのパーティーに約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
。理由は完全にはわかりません。誰かがその答えを持っているなら、私は興味があるでしょう。