[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Metaclasses

Neil Curzon

11/8/2007 3:46:00 AM

Hi, all. I'm trying to understand chapter 24 of Programming Ruby.
I'm using "metaid.rb" from why the lucky stiff's site to help with the
examples. (http://whytheluckystiff.net/articles/seeingMetaclassesCl...)

Everything is pretty straightforward except for the diagrams of
inheritance of metaclasses. Figure 24.2 indicates that for a direct
subclass of Object, its metaclass's superclass should be Object's
metaclass. When I try this out in irb, I don't get the expected
result.

$ irb -r metaid
irb(main):001:0> String.metaclass
=> #<Class:String>
irb(main):002:0> String.metaclass.superclass
=> #<Class:Class>
irb(main):003:0> String.metaclass.superclass == Object.metaclass
=> false

Surprisingly, when I try it in JRuby, I do get the expected result.

$ jirb -r metaid
irb(main):001:0> String.metaclass
=> #<Class:String>
irb(main):002:0> String.metaclass.superclass
=> #<Class:Object>
irb(main):003:0> String.metaclass.superclass == Object.metaclass
=> true

Also, figure 24.3 suggests that for an instance of String, the
metaclass should be a virtual class extending String itself.

Once again only JRuby produces the expected result.

$ irb -r metaid
irb(main):001:0> String.new.metaclass.superclass == String
=> false

$ jirb -r metaid
irb(main):001:0> String.new.metaclass.superclass == String
=> true

Something else I found weird is that when I go up the inheritance of a
String instance's metaclass in plain ruby, I quickly run into a loop:

$ irb -r metaid
irb(main):001:0> c = String.new.metaclass.superclass.superclass
=> #<Class:Class>
irb(main):002:0> c == c.superclass
=> true


Any help in understanding this would be greatly appreciated!

Thanks

Neil

7 Answers

Giles Bowkett

11/8/2007 4:31:00 AM

0

The JRuby discrepancies are very interesting and I don't know the
answer. I e-mailed Charlie Nutter from JRuby and hopefully he'll chime
in.

> Something else I found weird is that when I go up the inheritance of a
> String instance's metaclass in plain ruby, I quickly run into a loop:
>
> $ irb -r metaid
> irb(main):001:0> c = String.new.metaclass.superclass.superclass
> => #<Class:Class>
> irb(main):002:0> c == c.superclass
> => true
>
> Any help in understanding this would be greatly appreciated!

This part at least I can explain. I think.

In metaid.rb:

def metaclass; class << self; self; end; end

This means that when you use this method, you're just having the
object open up its class and return that to you. What you're running
into isn't really a loop so much as a fundamental particle. In the
universe it may be true that you can subdivide any particle into
smaller, "more fundamental" particles, but programming languages are
much tidier than infinity, and sooner or later you get to the first
turtle, and after that it's turtles all the way down. (I'm assuming
you can understand me, and if you're using _why's guide to Ruby,
there's a good chance I sound perfectly rational.) In real life every
turtle is made up of smaller turtles; inside a programming language,
when you hit the turtle, you're there.

In a nutshell, I believe this means that just as the topmost class is
Object, the topmost *class* is a Class:Class object. If that doesn't
help, there's a simpler way to see it. Object is the fundamental
class; all objects are ultimately Objects. Metaclasses have a parallel
hierarchy, and all classes are ultimately instances of a Class:Class
object - the object you've uncovered here. In a sense you've
discovered the Holy Grail of the metaclass shadow world.

(I'd probably be more coherent if I hadn't just spent about twenty
minutes reading _why's stuff on Shoes.)

--
Giles Bowkett

Blog: http://gilesbowkett.bl...
Portfolio: http://www.gilesg...
Tumblelog: http://giles.t...

Phrogz

11/8/2007 5:08:00 AM

0

On Nov 7, 8:46 pm, Neil Curzon <neil.cur...@gmail.com> wrote:
> Hi, all. I'm trying to understand chapter 24 of Programming Ruby.
> I'm using "metaid.rb" from why the lucky stiff's site to help with the
> examples. (http://whytheluckystiff.net/articles/seeingMetaclassesCl...)
>
> Everything is pretty straightforward except for the diagrams of
> inheritance of metaclasses. Figure 24.2 indicates that for a direct
> subclass of Object, its metaclass's superclass should be Object's
> metaclass. When I try this out in irb, I don't get the expected
> result.

Possibly this diagram will help:
http://phrogz.net/RubyLibs/RubyMethodLook...

David A. Black

11/8/2007 11:19:00 AM

0

Hi --

On Thu, 8 Nov 2007, Neil Curzon wrote:

> Hi, all. I'm trying to understand chapter 24 of Programming Ruby.
> I'm using "metaid.rb" from why the lucky stiff's site to help with the
> examples. (http://whytheluckystiff.net/articles/seeingMetaclassesCl...)
>
> Everything is pretty straightforward except for the diagrams of
> inheritance of metaclasses. Figure 24.2 indicates that for a direct
> subclass of Object, its metaclass's superclass should be Object's
> metaclass. When I try this out in irb, I don't get the expected
> result.
>
> $ irb -r metaid
> irb(main):001:0> String.metaclass
> => #<Class:String>
> irb(main):002:0> String.metaclass.superclass
> => #<Class:Class>
> irb(main):003:0> String.metaclass.superclass == Object.metaclass
> => false
>
> Surprisingly, when I try it in JRuby, I do get the expected result.
>
> $ jirb -r metaid
> irb(main):001:0> String.metaclass
> => #<Class:String>
> irb(main):002:0> String.metaclass.superclass
> => #<Class:Object>
> irb(main):003:0> String.metaclass.superclass == Object.metaclass
> => true

It actually depends which version of Ruby you use. The superclass
thing worked as expected in 1.8.2; then it stopped working (I'm not
sure why); and in 1.9 it's working again. ("Not working" doesn't mean
that the subclasses couldn't call the methods defined in their
superclasses' singleton classes, just that the superclass thing itself
was not in place.)

$ cat super.rb
class Object
def singleton_class
class << self; self; end
end
end

p String.singleton_class.superclass == Object.singleton_class

$ /usr/local/lib/ruby-1.8.2/bin/ruby -v super.rb
ruby 1.8.2 (2004-12-25) [i686-linux]
true
$ ruby -v super.rb
ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-linux]
false
$ /usr/local/lib/ruby-svn/bin/ruby -v super.rb
ruby 1.9.0 (2007-11-07 patchlevel 0) [i686-linux]
true


David

--
Upcoming training by David A. Black/Ruby Power and Light, LLC:
* Advancing With Rails, Edison, NJ, November 6-9
* Advancing With Rails, Berlin, Germany, November 19-22
* Intro to Rails, London, UK, December 3-6 (by Skills Matter)
See http://www.r... for details!

Rick DeNatale

11/8/2007 11:42:00 AM

0

On 11/8/07, David A. Black <dblack@rubypal.com> wrote:

> It actually depends which version of Ruby you use. The superclass
> thing worked as expected in 1.8.2; then it stopped working (I'm not
> sure why); and in 1.9 it's working again. ("Not working" doesn't mean
> that the subclasses couldn't call the methods defined in their
> superclasses' singleton classes, just that the superclass thing itself
> was not in place.)

interesting, I didn't realize that this had changed in 1.9.

Actually, it's not that anything isn't in place in 1.8, it's that the
implementation of Class#superclass skips classes in the superclass
chain, the same way that Object#class skips an instance singleton
class if there is one, and the ancestors methods replaces the wrapper
IClass nodes used to represent included modules in the behavior chain
of an object into the modules themselves in the result.

It's smoke and mirrors, and in the case of Ruby 1.9 it seems theres a
little less smoke and mirrors in Class#superclass.


--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Xavier Noria

11/8/2007 11:55:00 AM

0

On Nov 8, 2007, at 12:42 PM, Rick DeNatale wrote:

> On 11/8/07, David A. Black <dblack@rubypal.com> wrote:
>
>> It actually depends which version of Ruby you use. The superclass
>> thing worked as expected in 1.8.2; then it stopped working (I'm not
>> sure why); and in 1.9 it's working again. ("Not working" doesn't mean
>> that the subclasses couldn't call the methods defined in their
>> superclasses' singleton classes, just that the superclass thing
>> itself
>> was not in place.)
>
> interesting, I didn't realize that this had changed in 1.9.
>
> Actually, it's not that anything isn't in place in 1.8, it's that the
> implementation of Class#superclass skips classes in the superclass
> chain, the same way that Object#class skips an instance singleton
> class if there is one,

Singleton classes are created on-demand behind the scenes?

-- fxn


David A. Black

11/8/2007 11:55:00 AM

0

Hi --

On Thu, 8 Nov 2007, Rick DeNatale wrote:

> On 11/8/07, David A. Black <dblack@rubypal.com> wrote:
>
>> It actually depends which version of Ruby you use. The superclass
>> thing worked as expected in 1.8.2; then it stopped working (I'm not
>> sure why); and in 1.9 it's working again. ("Not working" doesn't mean
>> that the subclasses couldn't call the methods defined in their
>> superclasses' singleton classes, just that the superclass thing itself
>> was not in place.)
>
> interesting, I didn't realize that this had changed in 1.9.
>
> Actually, it's not that anything isn't in place in 1.8, it's that the
> implementation of Class#superclass skips classes in the superclass
> chain, the same way that Object#class skips an instance singleton
> class if there is one, and the ancestors methods replaces the wrapper
> IClass nodes used to represent included modules in the behavior chain
> of an object into the modules themselves in the result.

By "superclass thing itself not in place" I just meant that you get
false when you ask whether C's singleton class is the superclass of
D's singleton class. So any documentation/books/etc. that describe it
that way will seem wrong if you try it out in 1.8.6.

> It's smoke and mirrors, and in the case of Ruby 1.9 it seems theres a
> little less smoke and mirrors in Class#superclass.

Always a good sign :-)


David

--
Upcoming training by David A. Black/Ruby Power and Light, LLC:
* Advancing With Rails, Edison, NJ, November 6-9
* Advancing With Rails, Berlin, Germany, November 19-22
* Intro to Rails, London, UK, December 3-6 (by Skills Matter)
See http://www.r... for details!

Rick DeNatale

11/8/2007 12:18:00 PM

0

On 11/8/07, Xavier Noria <fxn@hashref.com> wrote:
> On Nov 8, 2007, at 12:42 PM, Rick DeNatale wrote:

> > Actually, it's not that anything isn't in place in 1.8, it's that the
> > implementation of Class#superclass skips classes in the superclass
> > chain, the same way that Object#class skips an instance singleton
> > class if there is one,
>
> Singleton classes are created on-demand behind the scenes?

Yes, at least in 1.8, and I can't imagine why that would change.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...