5

私はこのように呼び出すいくつかのメソッドを持っています:

with_this do
  with_that do
    and_in_this_context do
      yield
    end
  end
end

このようなブロック呼び出しを再帰的にラップするトリックがあったことを覚えています。ブロックラッピングを行うメソッドを作成するにはどうすればよいですか?

def in_nested_contexts(&blk)
  contexts = [:with_this, :with_that, :and_in_this_context]
  # ... magic probably involving inject
end
4

1 に答える 1

3

実際にinject、ネストされたラムダまたはプロシージャを作成するために使用できます。これらは最後に呼び出すことができます。指定されたブロックがネストの内部である必要があるため、配列を逆にしてそのブロックを初期値として使用し、連続する各関数をinjectの結果にラップします。

def in_nested_contexts(&blk)
  [:with_this, :with_that, :and_in_this_context].reverse.inject(blk) {|block, symbol|
    ->{ send symbol, &block }
  }.call
end

with_this、et alメソッドをbeforeステートメントとafterステートメントでラップすると、putsこれが実際に動作していることがわかります。

in_nested_contexts { puts "hello, world" }
#=> 
  with_this start
  with_that start
  context start
  hello, world
  context end
  with_that end
  with_this end
于 2013-03-27T02:28:49.640 に答える