[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

instance_eval or class_eval on metaclass?

Christopher J. Bottaro

7/11/2008 3:18:00 PM

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.

2 Answers

David A. Black

7/11/2008 3:29:00 PM

0

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
See http://www.r... for details and updates!

Christopher J. Bottaro

7/15/2008 1:42:00 AM

0

Ahh, thanks for clearing that up for me.

On Jul 11, 10:28=A0am, "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. =A0I've always been using #class_eval with
> > metaclasses and getting my desired effect. =A0So 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
> > =A0def metaclass
> > =A0 =A0class << self
> > =A0 =A0 =A0self
> > =A0 =A0end
> > =A0end
> > end
>
> > class Test
>
> > =A0def f
> > =A0 =A0metaclass.class_eval do
> > =A0 =A0 =A0puts self.inspect
> > =A0 =A0end
> > =A0end
>
> > =A0def g
> > =A0 =A0metaclass.instance_eval do
> > =A0 =A0 =A0puts self.inspect
> > =A0 =A0end
> > =A0end
>
> > end
>
> > t =3D 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
> =A0 =A0def singleton_class =A0 # Sorry; it's what makes sense to me.
> =A0 =A0 =A0class << self
> =A0 =A0 =A0 =A0self
> =A0 =A0 =A0end
> =A0 =A0end
> end
>
> class TestMe
>
> =A0 =A0def f
> =A0 =A0 =A0singleton_class.class_eval do
> =A0 =A0 =A0 =A0puts self.inspect
> =A0 =A0 =A0 =A0def x
> =A0 =A0 =A0 =A0 =A0puts "def in class_eval =3D=3D instance method"
> =A0 =A0 =A0 =A0end
> =A0 =A0 =A0end
> =A0 =A0end
>
> =A0 =A0def g
> =A0 =A0 =A0singleton_class.instance_eval do
> =A0 =A0 =A0 =A0puts self.inspect
> =A0 =A0 =A0 =A0def y
> =A0 =A0 =A0 =A0 =A0puts "def in obj. instance_eval =3D=3D singleton metho=
d on obj"
> =A0 =A0 =A0 =A0end
> =A0 =A0 =A0end
> =A0 =A0end
>
> end
>
> t =3D 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
> =3D> nil
> >> C.class_eval { def x; end }
> =3D> nil
> >> C.instance_eval { def y; end }
> =3D> nil
> >> C.new.x
> =3D> nil
> >> C.y
>
> =3D> nil
>
> David
>
> --
> Rails training from David A. Black and Ruby Power and Light:
> =A0 =A0Intro to Ruby on Rails =A0July 21-24 =A0 =A0 =A0Edison, NJ
> =A0 =A0Advancing With Rails =A0 =A0August 18-21 =A0 =A0Edison, NJ
> Seehttp://www.ruby... details and updates!