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 #<Foo:0x401c25b0> (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 <<Foo ... end".
>
> 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!