我想捕获块(具有相关名称),但不会改变它们的写入范围.下面的代码有两种捕获块(capt_a和capt_b)的方法.capt_a工作正常,我想capt_b以同样的方式工作.是否可以修改capt_b以使效果与capt_a?相同?
class Capturer
attr_reader :method, :block
def capt_a
yield self
self
end
def capt_b(&block)
instance_eval(&block)
self
end
def method_missing(method, &block)
@method = method
@block = block
end
end
# Example:
a = Capturer.new.capt_a{|capt| capt.foo{self} }.block
b = Capturer.new.capt_b{ foo{self} }.block
a.call # => main
b.call # => #<Capturer:0x000001008fb5c8 @method=:foo, @block=#<Proc:0x000001008fb500@temp.rb:23>>
# I would like 'main'
Run Code Online (Sandbox Code Playgroud)
在对@bioneuralnet建议的方向进行了一些研究后,可以创建一个新Proc的instance_eval来恢复上下文.该binding初始块是用来获得初始self.所以这是一个(有点难看)的解决方案:
def capture_b(&block)
instance_eval(&block)
the_desired_self = block.binding.eval("self")
bk = @block
@block = Proc.new{ the_desired_self.instance_eval(&bk) }
self
end
Run Code Online (Sandbox Code Playgroud)
它并不完美,因为它会更慢,因为原始块不会出现==在结果块中; 也许有更好的解决方案?
| 归档时间: |
|
| 查看次数: |
1387 次 |
| 最近记录: |