2

I have a container class Foo with a method frob, and I want to add a similarly named method, which will delegate to the container, to each of the contained elements.

First I tried

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

but this of course leads to SystemStackError: stack level too deep, as self is c at that point. I then tried

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

but local variables aren't part of the closure of the newly defined method, so I get undefined local variable or method 'parent'.

I came up with the following hack, which works:

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

However, it pollutes the variable space of the child with something that's only needed by this one method. How can I get parent/self in there while keeping the newly defined method self-contained?

David Moles
  • 48,006
  • 27
  • 136
  • 235

1 Answers1

2

This should work:

children.each do |c|
  parent = self
  c.send(:define_method, :frob) do
    parent.frob
  end
end
David Grayson
  • 84,103
  • 24
  • 152
  • 189