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

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

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

···

On Sat, 12 Jul 2008, Christopher J. Bottaro wrote:

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails July 21-24 Edison, NJ
   Advancing With Rails August 18-21 Edison, NJ
See http://www.rubypal.com for details and updates!

Ahh, thanks for clearing that up for me.

···

On Jul 11, 10:28 am, "David A. Black" <dbl...@rubypal.com> wrote:

Hi --

On Sat, 12 Jul 2008, Christopher J. Bottaro wrote:
> 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?

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

--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails July 21-24 Edison, NJ
Advancing With Rails August 18-21 Edison, NJ
Seehttp://www.rubypal.comfor details and updates!