Metaclasses

N

Neil Curzon

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/seeingMetaclassesClearly.html)

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
 
G

Giles Bowkett

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.blogspot.com
Portfolio: http://www.gilesgoatboy.org
Tumblelog: http://giles.tumblr.com/
 
P

Phrogz

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/seeingMetaclassesClearly.html)

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/RubyMethodLookupFlow.png
 
D

David A. Black

Hi --

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/seeingMetaclassesClearly.html)

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.rubypal.com for details!
 
R

Rick DeNatale

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

Xavier Noria

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
 
D

David A. Black

Hi --

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.rubypal.com for details!
 
R

Rick DeNatale

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

Singleton classes are created on-demand behind the scenes?

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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top