*_eval

Can somebody explain me, in detail, the differences between
aModule.instance_eval, aModule.module_eval and
aModule.class_eval?

I'm especially interested in the differences in context.

There must be a difference. If I replace aModule.module_eval
with aModule.instance_eval in one spcific situation, the
results differ, although self.inspect returns the same value...

Thanks.

gegroet,
Erik V. - http://www.erikveen.dds.nl/

···

----------------------------------------------------------------

class Object
   def metaclass
     class << self
       self
     end
   end
end

class Foo
   block =
   lambda do
     p [self, object_id]
   end

   2.times do
     instance_eval(&block)
     module_eval(&block)
     class_eval(&block)

     metaclass.instance_eval(&block)
     metaclass.module_eval(&block)
     metaclass.class_eval(&block)
   end
end

----------------------------------------------------------------

[Foo, -605291388]
[Foo, -605291388]
[Foo, -605291388]
[#<Class:Foo> , -605291428]
[#<Class:Foo> , -605291428]
[#<Class:Foo> , -605291428]
[Foo, -605291388]
[Foo, -605291388]
[Foo, -605291388]
[#<Class:Foo> , -605291428]
[#<Class:Foo> , -605291428]
[#<Class:Foo> , -605291428]

----------------------------------------------------------------

There must be a difference. If I replace aModule.module_eval
with aModule.instance_eval in one spcific situation, the
results differ, although self.inspect returns the same value...

Well, when you use keywords (like `def' 'alias') ruby use the
"current" class to know where it must define the method.

With #instance_eval, the current class is the singleton class and ruby
will define singleton methods

With #module_eval, the current is the class (i.e. self) and ruby define
instance methods.

By default, #class_eval is the same than #module_eval

Guy Decoux

Erik Veenstra wrote:

Can somebody explain me, in detail, the differences between
aModule.instance_eval, aModule.module_eval and
aModule.class_eval?

I'm especially interested in the differences in context.

...

  I think inspect() and object_id() confuse the issue, and trying to use
instance_eval() at module scope is about as much fun as putting a
screwdriver through your eye. My own views are as follows:
module_eval() is intended for defining methods dynamically, and its
receiver should be of class Module. Given

  module M; end
  mod = M # or some other module

I would use

  m.module_eval {
    def foo; end
  }

as a faster, cleaner way of accomplishing

  eval <<-EOS
    module #{m.to_s}
      def foo; end
    end
  EOS

which is hampered by its reliance on a string eval().
  On the other hand, I see instance_eval() as primarily useful for
*calling* a blockful of methods, with a dynamically-determined
receiver. Say you have a bunch of stuff you want some object to
do--e.g., you know it'll be Enumerable, so you have some Enumerable
methods--

  module Enumerable
    def func()
      any? whatever
      sort
      to_a
    end
  end

  enum.func()

but then you realize that you might want to use this more generally,
not just on Enumerable objects. So you wrap it:

  func = proc do
    any? whatever
    sort
    to_a
  end

and when you want somebody to call it, use

  obj.instance_eval &func

The alternative would be

  func = proc do |receiver|
    receiver.any? whatever
    receiver.sort
    receiver.to_a
  end

  func.call(obj)

which is a less elegant factorization.

...

I'll switch back to good old Lisp...

Good bye, brave Ruby people...

It was a nice time...

So long...

     Bye.

> There must be a difference. If I replace
> aModule.module_eval with aModule.instance_eval in one
> spcific situation, the results differ, although
> self.inspect returns the same value...

Well, when you use keywords (like `def' 'alias') ruby use the
"current" class to know where it must define the method.

With #instance_eval, the current class is the singleton class and ruby
will define singleton methods

With #module_eval, the current is the class (i.e. self) and ruby define
instance methods.

I never heard of this "current" before... Interesting... So,
although the contexts look the same (self and object_id), in
reality, they aren't...

POLS? Well, _I_ am surprised!

gegroet,
Erik V. - http://www.erikveen.dds.nl/

···

----------------------------------------------------------------

class Foo
   instance_eval <<-END
     p [self, object_id]

     def bar1
     end
   END

   module_eval <<-END
     p [self, object_id]

     def bar2
     end
   END
end

p Foo.method_defined?(:bar1)
p Foo.method_defined?(:bar2)

p Foo.new.method(:bar1) rescue nil # No output!
p Foo.new.method(:bar2) rescue nil

----------------------------------------------------------------

[Foo, -605293266]
[Foo, -605293266]
false
true
#<Method: Foo#bar2>

----------------------------------------------------------------

Well, when you use keywords (like `def' 'alias') ruby use the
> "current" class to know where it must define the method.

It's really only true for keyword stuff. define_method works as
expected...

POLS? Well, _I_ am surprised!

It's the first time, in all those years, that I'm surprised by
Ruby. Well, I'm often surprised by Ruby, but that's in a
positive way. Now I'm surprised in a negative way. I'm
surprised being surprised! It's a shock!

I'll switch back to good old Lisp...

Good bye, brave Ruby people...

It was a nice time...

So long...

gegroet,
Erik V. - http://www.erikveen.dds.nl/

···

----------------------------------------------------------------

class Foo
   instance_eval <<-END
     p [self, object_id]

     def bar1
     end

     define_method :bar2 do
     end
   END

   module_eval <<-END
     p [self, object_id]

     def bar3
     end

     define_method :bar4 do
     end
   END
end

p Foo.method_defined?(:bar1) # false
p Foo.method_defined?(:bar2) # true
p Foo.method_defined?(:bar3) # true
p Foo.method_defined?(:bar4) # true

p Foo.new.method(:bar1) rescue nil # no output!
p Foo.new.method(:bar2) rescue nil # #<Method: Foo#bar2>
p Foo.new.method(:bar3) rescue nil # #<Method: Foo#bar2>
p Foo.new.method(:bar4) rescue nil # #<Method: Foo#bar2>

----------------------------------------------------------------

[Foo, -605293706]
[Foo, -605293706]
false
true
true
true
#<Method: Foo#bar2>
#<Method: Foo#bar3>
#<Method: Foo#bar4>

----------------------------------------------------------------

I never heard of this "current" before... Interesting... So,
although the contexts look the same (self and object_id), in
reality, they aren't...

Well, I hope that you have seen that at toplevel (where self is an
*instance* of Object) ruby define instance method for Object.

When it's in the class A (where self is A) it define instance method for A

Guy Decoux

ts wrote:

> I never heard of this "current" before... Interesting... So,
> although the contexts look the same (self and object_id), in
> reality, they aren't...

Well, I hope that you have seen that at toplevel (where self is an
*instance* of Object) ruby define instance method for Object.

I've often wondered why it wasn't an instance of Module with an extend
self.

T.