Instance_eval or class_eval on metaclass?

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.