在Ruby中使用monkey-patching实例方法时注入外部作用域

时间:2015-05-26 23:50:22

标签: ruby closures metaprogramming

我有一个带有方法Foo的容器类frob,我想添加一个类似命名的方法,该方法将委托给容器,每个包含的元素。

首先我试过

  self.children.each do |c|
    def c.frob
      self.frob
    end
  end

但这当然导致SystemStackError: stack level too deep,因为此时selfc。然后我尝试了

  parent = self
  self.children.each do |c|
    def c.frob
      parent.frob
    end
  end

但是局部变量不是新定义方法的闭包的一部分,因此我得到undefined local variable or method 'parent'

我想出了下面的黑客,它起作用了:

  self.children.each do |c|
    c.instance_variable_set('@parent', self)
    def c.frob
      @parent.frob
    end
  end

但是,它会使用这一方法只需要的东西来污染孩子的变量空间。如何在保持新定义的方法自包含的同时获得parent / self

1 个答案:

答案 0 :(得分:2)

这应该有效:

children.each do |c|
  parent = self
  c.send(:define_method, :frob) do
    parent.frob
  end
end