From: Dan Doel Date: 2004-05-27T07:00:17+09:00 Subject: Re: ruby-dev summary 23459-23562 On Tuesday 25 May 2004 3:41 pm, Mark Hubbart wrote: > > define_method(:foo) { |arg| result = arg } > > foo(5); result # => 5 or ~> NameError? > > > > # Or more interesting: > > define_method(:foo) { foo = nil; return true } > > foo # => true or nil or NameError? > > foo # => true or nil? > > IIUC, the first snippet would give a NameError, the second would return > true twice. That's the way it is now... > > Why would rescoping rules be changed? Currently, when you call > define_method, Class.new, Module.new, etc., the block is rescoped (is > that the right word?) and local variables never leak in. So, assuming > they don't make a silly change, define_method would be _exactly_ > orthogonal to def...end: I don't think that's quite right. Currently, #define_method is useful for creating methods that capture the closure of where it's defined so: class Foo a = 4 define_method(:foo) do puts a end end class Bar a = 4 def foo puts a end end Foo.new.foo Bar.new.foo Prints "4" for the first call, and causes an error for the second. Now, scoping is changing in Ruby 2.0. Currently method { local = 5 } is scoped such that local can't be seen outside the block (assuming that there is no local defined outside the block). However, in 2.0, it will be equivalent to: local = nil method { local = 5 } So variables will automatically leak out of blocks. So in the case of: define_method(:foo) { bar = 5 } foo p bar You should get 5 printed out (if my understanding is correct). -- Dan