From: "David A. Black" Date: 2007-11-17T06:52:55+09:00 Subject: Re: "instance_eval" (eg, sent to a class object) Hi -- On Sat, 17 Nov 2007, Greg Weeks wrote: > I've poked around, but I don't get instance_eval at all. > > I do know what it means to evaluate code in the context of a *class* > object. Ie, I know what *this* does: > > class Foo > # We're now in the context of the object Foo. > C = 1 > class Bar > def bar ; "bar" ; end > end > def foo ; "foo" ; end > end > p Foo::C -> 1 > p Foo::Bar.new.bar -> "bar" > p Foo.new.foo -> "foo" > > Now let's try this again with "instance_eval": > > class Foo > end > Foo.instance_eval do > # We're now supposedly in the context of the object Foo. > C = 1 > class Bar > def bar ; "bar" ; end > end > def foo ; "foo" ; end > end > p Foo::C > p Foo::Bar.new.bar > p Foo.new.foo > > Nothing works as I expected. The result is: > > tmp.rb:26: warning: toplevel constant C referenced by Foo::C > 1 > tmp.rb:27: warning: toplevel constant Bar referenced by Foo::Bar > "bar" > tmp.rb:28: undefined method `foo' for # (NoMethodError) > > Evidentally, C and Bar scoped lexically, rather than being in the > context of Foo. And the foo definition ended up in the context of > "class < > So, hat in hand, I ask for a description of "instance_eval". It changes 'self' to the receiver, for the duration of the block. That's pretty much all it does. So here: class A end "hello".instance_eval { class B; end } class B doesn't care that some string has become self; it still considers itself a top-level class definition. David -- Upcoming training by David A. Black/Ruby Power and Light, LLC: * Advancing With Rails, Berlin, Germany, November 19-22 * Intro to Rails, London, UK, December 3-6 (by Skills Matter) See http://www.rubypal.com for details!