From: Robert Klemme Date: 2010-02-15T17:28:37+09:00 Subject: Re: 'def', but with a closure 2010/2/15 Albert Schlef : > It occurred to me several times that I wanted to do: > >  @cars.each do |owner, model| >    widget = TkLabel.new(:text => model) >    def widget.get_owner >      return owner >    end >  end > > But, of course, this doesn't work because the code inside 'def' doesn't > see the enveloping variables, so the 'owner' within the 'def' isn't > recognized. > > So instead I do: > >  @cars.each do |owner, model| >    widget = TkLabel.new(:text => model) >    meta = (class << widget; self; end) >    meta.send(:define_method, :get_owner) do >      return owner >    end >  end > > It work. Yet, it looks a bit ugly. Is there any "nicer" way I'm missing? You can at least shorten it a bit @cars.each do |owner, model| widget = TkLabel.new(:text => model) (class << widget; self; end).send(:define_method, :get_owner) do owner end end I find this better than other approaches because storing in an instance variable is not the same as using the closure. Josh's approach with eval has the disadvantage of a) using eval in the first place, b) it does not work for all types of objects handed in as owner and c) for Strings it's less efficient because it will create a new String instance every time the method is invoked. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/