Ruby 在按名称接受块的方法调用中包装块

Ruby 在按名称接受块的方法调用中包装块,ruby,block,Ruby,Block,我有很多方法可以这样调用: 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 proba

我有很多方法可以这样调用:

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

您确实可以使用
inject
来创建嵌套的lambda或proc,您可以在最后调用它们。您需要将给定的块作为嵌套的内部,因此可以反转数组并使用该块作为初始值,然后将每个后续函数围绕inject的结果进行包装:

def in_nested_contexts(&blk)
  [:with_this, :with_that, :and_in_this_context].reverse.inject(blk) {|block, symbol|
    ->{ send symbol, &block }
  }.call
end
如果用this等方法和before和after
put
语句包装
,您可以看到它的作用:

in_nested_contexts { puts "hello, world" }
#=> 
  with_this start
  with_that start
  context start
  hello, world
  context end
  with_that end
  with_this end