8

私はコードを期待しています

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>

4

2 に答える 2

5

&foofooにブロックとして渡そうとし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の違いに関する詳細情報

于 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 に答える