I was looking at someone’s implementation of #meta_eval and I noticed
they used #instance_eval. I’ve always been using #class_eval with
metaclasses and getting my desired effect. So why use #instance_eval
over #class_eval when working with metaclasses?
Furthermore, I can’t even tell a difference, as demonstrated by this
code snippet.
class Object
def metaclass
class << self
self
end
end
end
class Test
def f
metaclass.class_eval do
puts self.inspect
end
end
def g
metaclass.instance_eval do
puts self.inspect
end
end
end
t = Test.new
t.f
t.g
#<Class:#Test:0x8eae4>
#<Class:#Test:0x8eae4>
Using #class_eval and #instance_eval both produce the same result.
Can anyone shed some light on this subject?
Thanks.
Hi –
On Sat, 12 Jul 2008, Christopher J. Bottaro wrote:
class << self
end
t = Test.new
t.f
t.g
#<Class:#Test:0x8eae4>
#<Class:#Test:0x8eae4>
Using #class_eval and #instance_eval both produce the same result.
Can anyone shed some light on this subject?
They give you the same self but they behave differently in the face of
‘def’.
class Object
def singleton_class # Sorry; it’s what makes sense to me.
class << self
self
end
end
end
class TestMe
def f
singleton_class.class_eval do
puts self.inspect
def x
puts “def in class_eval == instance method”
end
end
end
def g
singleton_class.instance_eval do
puts self.inspect
def y
puts “def in obj. instance_eval == singleton method on obj”
end
end
end
end
t = TestMe.new
t.f
t.g
t.x
t.singleton_class.y
You can see the same thing one level down too:
class C; end
=> nil
C.class_eval { def x; end }
=> nil
C.instance_eval { def y; end }
=> nil
C.new.x
=> nil
C.y
=> nil
David
Ahh, thanks for clearing that up for me.