*_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]

“E” == Erik V. [email protected] 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

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>

Erik V. 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 wrote:

“E” == Erik V. [email protected] 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.

“E” == Erik V. [email protected] 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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs