[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Erik Veenstra

7/22/2006 4:02:00 PM

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.erikve...

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

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]

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


6 Answers

ts

7/22/2006 5:24:00 PM

0

>>>>> "E" == Erik Veenstra <erikveen@gmail.com> writes:

E> There must be a difference. If I replace aModule.module_eval
E> with aModule.instance_eval in one spcific situation, the
E> 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

7/22/2006 5:42:00 PM

0

> > 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.erikve...

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

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>

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


Erik Veenstra

7/22/2006 6:05:00 PM

0

> 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.erikve...

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

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>

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


Dumaiu

7/22/2006 8:11:00 PM

0

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.

ts

7/23/2006 9:51:00 AM

0

>>>>> "E" == Erik Veenstra <erikveen@gmail.com> writes:

E> I never heard of this "current" before... Interesting... So,
E> although the contexts look the same (self and object_id), in
E> 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

Trans

7/23/2006 11:47:00 AM

0


ts wrote:
> >>>>> "E" == Erik Veenstra <erikveen@gmail.com> writes:
>
> E> I never heard of this "current" before... Interesting... So,
> E> although the contexts look the same (self and object_id), in
> E> 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.