ruby - 向过程生成块( 或者创建从生成的过程接受块的方法)

  显示原文与译文双语对照的内容
0 0

我目前正在处理一个接口,它允许我用一个触发链来包装任意方法调用。 如果不进入太多细节,我现在有一个接口接受如下内容:

class Spy
 def initialize
 @procs = []
 end
 def wrap(&block)
 @procs <<block
 end
 def execute
 original_proc = Proc.new { call_original }
 @procs.reduce(original_proc) do |memo, p|
 Proc.new { p.call &memo }
 end.call
 end
 def call_original
 puts 'in the middle'
 end
end
spy = Spy.new
spy.wrap do |&block|
 puts 'hello'
 block.call
end
spy.wrap do |&block|
 block.call
 puts 'goodbye'
end
spy.execute

不过我想做的是从API中删除 |&block|block.call,而使用 yield

spy.wrap do
 puts 'hello'
 yield
end

这并没有起作用,引发了 LocalJumpError: no block given (yield) 错误。

我还尝试通过在reduce中通过 define_singleton_method 来创建方法,但是我没有任何运气。

def execute
 original_proc = Proc.new { call_original }
 @procs.reduce(original_proc) do |memo, p|
 define_singleton_method :hello, &p
 Proc.new { singleton_method(:hello).call(&memo) }
 end.call
end

我可以用另一种方法? 仍然是从流程或者使用过程初始化某些可以引发的事件的yield

时间: 原作者:

0 0

除非将块传递给调用方本身,否则在wrap块中使用 yield 没有什么意义:

def foo
 spy.wrap do
 puts"executed in wrap from foo"
 yield
 end
end

如果调用 foo 没有块,它将引发异常,因为 yield 找不到要执行的块。 但是,如果将块传递给 foo 方法,则它将被调用:

foo do
 puts"foo block"
end

将输出

executed in wrap from foo
foo block

总之,我认为你误解了 yield的工作方式,我认为这不是你想要实现的。

...