# Superclass of eigenclass

**URL:** <https://rubytalk.org/t/superclass-of-eigenclass/53284>\
**Category:** ruby-talk\
**Created:** [7 May 2009 12:35 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284 "2009-05-07T12:35:17Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Danny\_O\_cuiv](https://avatars.discourse-cdn.com/v4/letter/d/6bbea6/32.png) [@Danny\_O\_cuiv](https://rubytalk.org/u/Danny_O_cuiv)\
**Post date:** [7 May 2009 12:35 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/1 "2009-05-07T12:35:17Z")

</div>

On page 261 of The Ruby Programming Language, they state:

"Class objects are special: they have superclasses. The eigenclasses of  
class objects are also special: they have superclasses, too. The  
eigenclass of an ordinary object stands alone and has no superclass."

This last sentence has me puzzled. The only possible interpretations  
that I can imagine would be that calling superclass on the eigenclass of  
an ordinary object would result in either (a) a method not found or (b)  
the value nil being returned. However, neither of these is the case.

Adding the usual eigenclass method to class Object, we then get in irb  
(ruby 1.8.7 on Mac OS X):

> greeting = "hello"

=\> "hello"

> greeting.eigenclass

=\> #\<Class:#\<String:0xb7cf5a14\>\>

> greeting.eigenclass.superclass

=\> #\<Class:String\>

I interpret #\<Class:#\<String:0xb7cf5a14\>\> as "a class object for the  
string object at 0xb7cf5a14".  
I interpret #\<Class:String\> as "a class object for class String".

This seems reasonable but conflicts with the description given in TRPL  
at the top. Any ideas?

Danny.

P.S. In my searches before posting I came across the following that  
no-one replied to. It seems that there are variations on the behaviour.

[http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/248178](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/248178)

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Greg\_Brown1](https://avatars.discourse-cdn.com/v4/letter/g/258eb7/32.png) [@Greg\_Brown1](https://rubytalk.org/u/Greg_Brown1)\
**Post date:** [7 May 2009 13:24 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/2 "2009-05-07T13:24:46Z")

</div>

> On page 261 of The Ruby Programming Language, they state:
> 
> "Class objects are special: they have superclasses. The eigenclasses of  
> class objects are also special: they have superclasses, too. The  
> eigenclass of an ordinary object stands alone and has no superclass."
> 
> This last sentence has me puzzled. The only possible interpretations  
> that I can imagine would be that calling superclass on the eigenclass of  
> an ordinary object would result in either (a) a method not found or (b)  
> the value nil being returned. However, neither of these is the case.

Not exactly an answer to your question, but here are some thoughts.

> > class A  
> > &nbsp;&nbsp;p ancestors  
> > end

[A, Object, Kernel]

> > class A  
> > &nbsp;&nbsp;f = class \<\< self; self; end  
> > &nbsp;&nbsp;p f.ancestors  
> > end

[Class, Module, Object, Kernel]

> > a = "a"

=\> "a"

> > k = class \<\< a; self; end

=\> #\<Class:#\<String:0x25ad14\>\>

> > k.ancestors

=\> [String, Enumerable, Comparable, Object, Kernel]

> **···**
>
> On Thu, May 7, 2009 at 8:35 AM, Danny O cuiv \<danny.ocuiv@gmail.com\> wrote:

---

<div class="post-metadata">

**Author:** ![Rick\_DeNatale1](https://avatars.discourse-cdn.com/v4/letter/r/bbce88/32.png) [@Rick\_DeNatale1](https://rubytalk.org/u/Rick_DeNatale1)\
**Post date:** [7 May 2009 15:50 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/3 "2009-05-07T15:50:25Z")

</div>

I'm pretty sure that this is a typo.

Eigenclasses of ordinary objects certainly do have superclasses,  
that's how methods not defined in the singleton class sent to the  
ordinary object get resolved.

Two things that the eigenclass of an ordinary object can't have that  
and eigenclass of a class (which I for one prefer to call a metaclass)  
can have is:

1. A subclass  
2. Any instances besides that singleton ordinary object, which is why  
you get an exception of you try to send new to such an eigenclass.

I've long maintained that Ruby would be quite a bit clearer if we  
cleaned up this singleton vs. eigen vs. meta class thing. The fact  
that MRI uses a single flag bit marked singleton for both singleton  
classes and metaclasses, an implementation artifact which is pretty  
much hidden by the internal implementation of methods like class,  
ancestors etc. just tends to confuse people.

But that's just my opinion.

> **···**
>
> On Thu, May 7, 2009 at 8:35 AM, Danny O cuiv \<danny.ocuiv@gmail.com\> wrote:
> 
> > On page 261 of The Ruby Programming Language, they state:
> > 
> > "Class objects are special: they have superclasses. The eigenclasses of  
> > class objects are also special: they have superclasses, too. The  
> > eigenclass of an ordinary object stands alone and has no superclass."
> 
> --  
> Rick DeNatale
> 
> Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
> Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
> WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
> LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![David\_Flanagan](https://avatars.discourse-cdn.com/v4/letter/d/aca169/32.png) [@David\_Flanagan](https://rubytalk.org/u/David_Flanagan)\
**Post date:** [13 May 2009 21:55 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/4 "2009-05-13T21:55:05Z")

</div>

> On page 261 of The Ruby Programming Language, they state:
> 
> "Class objects are special: they have superclasses. The eigenclasses of  
> class objects are also special: they have superclasses, too. Theeigenclassof an ordinary object stands alone and has nosuperclass."

The text you quote does not match the behavior of any version of Ruby  
I can find--I don't recall what I was thinking when I wrote this.  
I'll fix this. The description of how method lookup works (and how  
class methods are inherited) is conceptually correct, however.

I think it is best to regard the superclass of an eigenclass as an  
implementation-defined construct, and not something you can rely on.  
As noted throughout this thread, Ruby has fuzzy boundaries between  
implementation and specification. And also, superclass and related  
methods play some tricks on you. The link you provide to an earlier  
ruby-talk message points out that the superclass of an eigenclass is  
one way in 1.8.2 and 1.9.x, and is another way in 1.8.6 and 1.8.7.  
My experimentation shows that jruby 1.0 works the way ruby 1.9 does in  
this regard.

Let's discuss only Ruby 1.9 for now. In this version, I believe that  
if o is an object that is not a class, then:

&nbsp;&nbsp;&nbsp;&nbsp;o.eigenclass.superclass == o.class

Given this, then the method lookup algorithm for o is simple to  
describe. Begin with the eigenclass of o and climb the superclass  
chain until the method is found. (Where the superclass chain is not  
the same thing that is returned by the superclass method, because the  
superclass method skips over modules)

Now suppose that o is the Fixnum class, and let's use ' to designate  
an eigenclass: Fixnum', Integer' and so on. In this case, methods are  
looked up in this hierarchy:

&nbsp;&nbsp;&nbsp;Fixnum'-\>Integer'-\>Numeric'-\>Object'-\>BasicObject'-\>Class-\>Module-

> Object-\>Kernel-\>BasicObject

Notice that the eigenclass of the Comparable module is omitted here.  
Fixnum does not inherit class methods from ancestors that are modules.

I believe that method inheritance works the same way in all recent  
versions of ruby, but that the observability of the inheritance chain  
through eigenclasses varies. Don't try this with Ruby 1.8.6 or Ruby  
1.8.7.

> **···**
>
> On May 7, 5:35 am, Danny O cuiv \<danny.oc...@gmail.com\> wrote:
> 
> > This last sentence has me puzzled. The only possible interpretations  
> > that I can imagine would be that callingsuperclasson theeigenclassof  
> > an ordinary object would result in either (a) a method not found or (b)  
> > the value nil being returned. However, neither of these is the case.
> > 
> > Adding the usualeigenclassmethod to class Object, we then get in irb  
> > (ruby 1.8.7 on Mac OS X):
> > 
> > \> greeting = "hello"  
> > =\> "hello"  
> > \> greeting.eigenclass  
> > =\> #\<Class:#\<String:0xb7cf5a14\>\>  
> > \> greeting.eigenclass.superclass  
> > =\> #\<Class:String\>
> > 
> > I interpret #\<Class:#\<String:0xb7cf5a14\>\> as "a class object for the  
> > string object at 0xb7cf5a14".  
> > I interpret #\<Class:String\> as "a class object for class String".
> > 
> > This seems reasonable but conflicts with the description given in TRPL  
> > at the top. Any ideas?
> > 
> > Danny.
> > 
> > P.S. In my searches before posting I came across the following that  
> > no-one replied to. It seems that there are variations on the behaviour.
> > 
> > [http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/248178](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/248178)  
> > --  
> > Posted viahttp://www.ruby-forum.com/.

---

<div class="post-metadata">

**Author:** ![Rick\_DeNatale1](https://avatars.discourse-cdn.com/v4/letter/r/bbce88/32.png) [@Rick\_DeNatale1](https://rubytalk.org/u/Rick_DeNatale1)\
**Post date:** [7 May 2009 16:21 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/5 "2009-05-07T16:21:41Z")

</div>

Just for the record, I just submitted the following erratum report to  
the O'Reilly site for the book:

Page 261 2nd Paragraph:  
The paragraph says:

"Class objects are special: they have superclasses. The eigenclasses of  
class objects are also special: they have superclasses, too. The  
eigenclass of an ordinary object stands alone and has no superclass."

Both the eigenclass of a class object and the eigenclass of an  
ordinary object have a superclass. If not then sending a message to  
an ordinary object would end up invoking method\_missing.

I think that the paragraph should read:

"Class objects are special: they can have subclasses. The eigenclasses of  
class objects are also special: they can have subclasses, too. The  
eigenclass of an ordinary object can have neither a subclass, nor any  
other instance except that single ordinary object. If an ordinary  
object with an eigenclass is duplicated with the Object#dup method,  
the duplicate will not acquire any of it's singleton methods. If it is  
cloned with the Object#clone method, the result will get an eigenclass  
which is a duplicate of the original objects eigenclass, so that each  
eigenclass has but a single instance."

The following ruby code (which behaves identically on Ruby 1.8.6,  
1.8.7 and 1.9.1) illustrates the above:

module Kernel  
&nbsp;&nbsp;def eigenclass  
&nbsp;&nbsp;&nbsp;&nbsp;class \<\< self;self;end  
&nbsp;&nbsp;end  
end

class TestClass

&nbsp;&nbsp;def bar  
&nbsp;&nbsp;&nbsp;&nbsp;:bar  
&nbsp;&nbsp;end

&nbsp;&nbsp;def self.foo  
&nbsp;&nbsp;&nbsp;&nbsp;:foo  
&nbsp;&nbsp;end  
end

t = TestClass.new  
def t.gorp  
&nbsp;&nbsp;:gorp  
end

p t\_eigenclass = t.eigenclass # =\> #\<Class:#\<TestClass:0x232d0\>\>  
p t\_eigenclass.superclass # =\> #\<Class:TestClass\>

p t.bar # =\> :bar  
p t.gorp # =\> :gorp

p t\_dup = t.dup  
p t\_clone = t.clone  
p t\_clone.respond\_to?(:gorp) # =\> true  
p t\_clone.eigenclass == t\_eigenclass # =\> false  
p t\_dup.respond\_to?(:gorp) # =\> false

p t.class.foo # =\> :foo  
p t.eigenclass.foo # =\> :foo

> **···**
>
> On Thu, May 7, 2009 at 11:50 AM, Rick DeNatale \<rick.denatale@gmail.com\> wrote:
> 
> > On Thu, May 7, 2009 at 8:35 AM, Danny O cuiv \<danny.ocuiv@gmail.com\> wrote:
> > 
> > > On page 261 of The Ruby Programming Language, they state:
> > > 
> > > "Class objects are special: they have superclasses. The eigenclasses of  
> > > class objects are also special: they have superclasses, too. The  
> > > eigenclass of an ordinary object stands alone and has no superclass."
> > 
> > I'm pretty sure that this is a typo.
> 
> --  
> Rick DeNatale
> 
> Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
> Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
> WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
> LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![Danny\_O\_cuiv](https://avatars.discourse-cdn.com/v4/letter/d/6bbea6/32.png) [@Danny\_O\_cuiv](https://rubytalk.org/u/Danny_O_cuiv)\
**Post date:** [7 May 2009 17:17 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/6 "2009-05-07T17:17:43Z")

</div>

Hi Rick,

I suspect that you're right that the text is incorrect. I doubt that  
it's a typo (in the sense of something that was fat-fingered) as the  
three sentences, taken together, are consistent in what they express. As  
such, it seems mistaken, which makes me curious to know what they were  
intending to say.

Your investigation of the issue corresponds with mine. I would, however,  
take issue with an aspect of your revised wording, specifically the  
following:

> The eigenclass of an ordinary object can have neither a subclass,  
> nor any other instance except that single ordinary object.

The ordinary object is not an instance of the eigenclass. In your  
example, the ordinary object is an instance of TestClass, not of any  
eigenclass. Indeed, there would be a bootstrapping problem if you  
regarded the ordinary object as an instance of the eigenclass. (You can  
only have an eigenclass in the context of an existing object, so you  
couldn't have created that object in the first place by instantiating  
the eigenclass.)

The same issue appears in the following statement:

> If it is cloned with the Object#clone method, the result will get an eigenclass  
> which is a duplicate of the original objects eigenclass, so that each  
> eigenclass has but a single instance."

Regards,

Danny

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![David\_Flanagan](https://avatars.discourse-cdn.com/v4/letter/d/aca169/32.png) [@David\_Flanagan](https://rubytalk.org/u/David_Flanagan)\
**Post date:** [13 May 2009 22:05 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/7 "2009-05-13T22:05:03Z")

</div>

> \>\> On page 261 of The Ruby Programming Language, they state:
> 
> \>\> "Class objects are special: they have superclasses. The eigenclasses of  
> \>\> class objects are also special: they have superclasses, too. The  
> \>\>eigenclassof an ordinary object stands alone and has nosuperclass."
> 
> \> I'm pretty sure that this is a typo.
> 
> Just for the record, I just submitted the following erratum report to  
> the O'Reilly site for the book:

Rick,

It wasn't a typo, and it correctly describes how method inheritance  
works, but it doesn't reflect the reality of the superclass method of  
eigenclasses.

Your suggested replacement text won't work as a replacement--the point  
of the paragraph in question is to explain method inheritance, not to  
get into the nitty gritty about eigenclasses.

Having said that, I should perhaps try to fit some of these eigenclass  
details into my next edition, as well as your argument for why the  
term "singleton class" makes sense.

&nbsp;&nbsp;&nbsp;&nbsp;David Flanagan

> **···**
>
> On May 7, 9:21 am, Rick DeNatale \<rick.denat...@gmail.com\> wrote:
> 
> > On Thu, May 7, 2009 at 11:50 AM, Rick DeNatale \<rick.denat...@gmail.com\> wrote:  
> > \> On Thu, May 7, 2009 at 8:35 AM, Danny O cuiv \<danny.oc...@gmail.com\> wrote:
> 
> > Page 261 2nd Paragraph:  
> > The paragraph says:
> > 
> > "Class objects are special: they have superclasses. The eigenclasses of  
> > class objects are also special: they have superclasses, too. Theeigenclassof an ordinary object stands alone and has nosuperclass."
> > 
> > Both theeigenclassof a class object and theeigenclassof an  
> > ordinary object have asuperclass. If not then sending a message to  
> > an ordinary object would end up invoking method\_missing.
> > 
> > I think that the paragraph should read:
> > 
> > "Class objects are special: they can have subclasses. The eigenclasses of  
> > class objects are also special: they can have subclasses, too. Theeigenclassof an ordinary object can have neither a subclass, nor any  
> > other instance except that single ordinary object. If an ordinary  
> > object with aneigenclassis duplicated with the Object#dup method,  
> > the duplicate will not acquire any of it's singleton methods. If it is  
> > cloned with the Object#clone method, the result will get aneigenclass  
> > which is a duplicate of the original objectseigenclass, so that eacheigenclasshas but a single instance."
> > 
> > The following ruby code (which behaves identically on Ruby 1.8.6,  
> > 1.8.7 and 1.9.1) illustrates the above:
> > 
> > module Kernel  
> > defeigenclass  
> > class \<\< self;self;end  
> > end  
> > end
> > 
> > class TestClass
> > 
> > def bar  
> > :bar  
> > end
> > 
> > def self.foo  
> > :foo  
> > end  
> > end
> > 
> > t = TestClass.new  
> > def t.gorp  
> > :gorp  
> > end
> > 
> > p t\_eigenclass = t.eigenclass# =\> #\<Class:#\<TestClass:0x232d0\>\>  
> > p t\_eigenclass.superclass# =\> #\<Class:TestClass\>
> > 
> > p t.bar # =\> :bar  
> > p t.gorp # =\> :gorp
> > 
> > p t\_dup = t.dup  
> > p t\_clone = t.clone  
> > p t\_clone.respond\_to?(:gorp) # =\> true  
> > p t\_clone.eigenclass== t\_eigenclass # =\> false  
> > p t\_dup.respond\_to?(:gorp) # =\> false
> > 
> > p t.class.foo # =\> :foo  
> > p t.eigenclass.foo # =\> :foo
> > 
> > --  
> > Rick DeNatale
> > 
> > Blog:[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
> > Twitter:[http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
> > WWR:[http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
> > LinkedIn:[http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![Rick\_DeNatale1](https://avatars.discourse-cdn.com/v4/letter/r/bbce88/32.png) [@Rick\_DeNatale1](https://rubytalk.org/u/Rick_DeNatale1)\
**Post date:** [7 May 2009 18:26 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/8 "2009-05-07T18:26:05Z")

</div>

> The ordinary object is not an instance of the eigenclass. In your  
> example, the ordinary object is an instance of TestClass, not of any  
> eigenclass.

Well instance is one of those things which the smoke and mirrors in  
MRI makes muddy.

Another example is superclass. One definition is that a is a  
superclass of b if the superclass slot of b points to a. This is the  
sense that the superclass of a class'es eigenclass is the eigenclass  
of the classes superclass.

But if you define superclass as what gets returned by the superclass  
method, then MRI obscures the truth:

String.eigenclass # =\> #\<Class:String\>  
Object.eigenclass # =\> #\<Class:Object\>  
String.superclass # =\> Object  
String.eigenclass.superclass # =\> #\<Class:Class\>

If you go in and look at the implementation, you'll find that the  
eigenclass of String has a superclass slot which points to the  
eigenclass of Object, but the superclass method implementation skips  
past 'singleton' classes, until it gets to \<Class:Class\>

Now the instance\_of? method does the same thing, it skips over  
'singleton' classes.

So what I'm really talking about is that a singleton class of an  
ordinary object has a singleton instance, which is the only meaning of  
singleton class which ever made sense to me.

> Indeed, there would be a bootstrapping problem if you  
> regarded the ordinary object as an instance of the eigenclass. (You can  
> only have an eigenclass in the context of an existing object, so you  
> couldn't have created that object in the first place by instantiating  
> the eigenclass.)

That's only if you tie the notion of instantiation and instance too  
closely, I don't see it that way.

> **···**
>
> On Thu, May 7, 2009 at 1:17 PM, Danny O cuiv \<danny.ocuiv@gmail.com\> wrote:
> 
> --  
> Rick DeNatale
> 
> Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
> Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
> WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
> LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![Forum](https://avatars.discourse-cdn.com/v4/letter/f/43a26b/32.png) [@Forum](https://rubytalk.org/u/Forum)\
**Post date:** [7 May 2009 18:27 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/9 "2009-05-07T18:27:56Z")

</div>

I did not read that Rick said anything about instantiating, but for  
what I am concerned he sure is right  
because of this:

irb(main):006:0\> a=Object::new  
=\> #\<Object:0x872e658\>  
irb(main):007:0\> s=class \<\< a; self end  
=\> #\<Class:#\<Object:0x872e658\>\>  
irb(main):008:0\> a.is\_a? s  
=\> true  
irb(main):009:0\> s::new  
TypeError: can't create instance of singleton class  
&nbsp;&nbsp;from (irb):9:in `new'  
&nbsp;&nbsp;from (irb):9  
&nbsp;&nbsp;from /usr/local/bin/irb:12:in `\<main\>'

Cheers  
R.

> **···**
>
> On Thu, May 7, 2009 at 7:17 PM, Danny O cuiv \<danny.ocuiv@gmail.com\> wrote:
> 
> > Hi Rick,
> > 
> > I suspect that you're right that the text is incorrect. I doubt that  
> > it's a typo (in the sense of something that was fat-fingered) as the  
> > three sentences, taken together, are consistent in what they express. As  
> > such, it seems mistaken, which makes me curious to know what they were  
> > intending to say.
> > 
> > Your investigation of the issue corresponds with mine. I would, however,  
> > take issue with an aspect of your revised wording, specifically the  
> > following:
> > 
> > > The eigenclass of an ordinary object can have neither a subclass,  
> > > nor any other instance except that single ordinary object.
> > 
> > The ordinary object is not an instance of the eigenclass. In your  
> > example, the ordinary object is an instance of TestClass, not of any  
> > eigenclass. Indeed, there would be a bootstrapping problem if you  
> > regarded the ordinary object as an instance of the eigenclass. (You can  
> > only have an eigenclass in the context of an existing object, so you  
> > couldn't have created that object in the first place by instantiating  
> > the eigenclass.)

---

<div class="post-metadata">

**Author:** ![Danny\_O\_cuiv](https://avatars.discourse-cdn.com/v4/letter/d/6bbea6/32.png) [@Danny\_O\_cuiv](https://rubytalk.org/u/Danny_O_cuiv)\
**Post date:** [7 May 2009 20:39 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/10 "2009-05-07T20:39:00Z")

</div>

Rick, Robert,

Thanks for your helpful replies. I have just introduced myself to Ruby  
in the last couple of weeks by reading The Ruby Programming Language, so  
I'm still trying to pin some concepts. One thing I have found  
interesting in looking things up online is that it's not uncommon to  
refer to C-level constructs in MRI when discussing language semantics.  
(I personally would prefer to restrict myself to what's observable from  
sample Ruby code.)

Firstly, Robert, you have used "is\_a?" in your example. This tests for  
(direct or indirect) conformance. I quibbled with the notion that the  
ordinary object was an instance of the eigenclass. The normal usage of  
the term "instance" to mean "direct instance" is reflected in the  
semantics of Ruby's "instance\_of?" method. Using this method, we could  
extend your sample code as follows:

> a.instance\_of? s

=\> false

> a.instance\_of? Object

=\> true

This is what I meant, and to me, this is significant. One of my  
reference points in reading about Ruby was Smalltalk, which has the  
notion of a metaclass. In Smalltalk the concept is clear. (Indeed, the  
only reasonable meaning for the term metaclass is "a class whose  
instances are classes".) In Ruby, some people contend that eigenclass  
and metaclass are synonyms, which seems to me to confuse two distinct  
notions. In the interests of conceptual clarity, here's my take on the  
two notions. (Feel free to poke holes in this if it's totally  
upside-down or otherwise mistaken.)

(a) Eigenclass  
Ruby allows for per-instance methods (deliberately avoiding the more  
common term as it's overloaded with a well-known pattern). The  
conceptual container for these per-instance methods is the object's  
eigenclass. The precise implementation of this notion in the reference  
notion should be immaterial. What is important is that a decision was  
made to reify the notion by providing language syntax to open it up, as  
follows:  
class \<\< myObject  
This allows for dealing with several per-instance methods together. More  
to the point, if this syntax was not part of the language, eigenclasses  
would be purely an implementation notion and have no correspondence in  
Ruby code.

(b) Metaclass  
To me, there is only one metaclass in Ruby, namely class Class. (By any  
reasonable definition of the term metaclass.) It seems to me mistaken to  
equate the terms metaclass and eigenclass. For one thing, every object  
in Ruby has an eigenclass (not just class objects). Secondly, even if we  
restrict our consideration purely to eigenclasses of class objects,  
these don't really qualify as metaclasses either. In Smalltalk, every  
class object is a (direct) instance of a metaclass. In Ruby, class  
objects are not (direct) instances of any eigenclass; they are all  
(direct) instances of class Class.

From this, it would seem to me that the term metaclass should not be  
used in Ruby. (Flanagan and Matz possibly agree as they seem to largely  
avoid the term in their book).

I would, however, agree with Rick about the muddiness surrounding  
superclasses. For example, the example on page 294-295-296 of the book  
uses the eigenclass to wrap tracing code around methods. In doing so,  
they use a call to super to access the original implementation. Now  
super, by the definition on page 238, "invokes a method with the same  
name as the current one, in the superclass of the current class". So,  
for this to work, the superclass of the eigenclass needs to be the  
original class. In other words, let's say we have a class called X, an  
instance of that class called x and let's say the eigenclass of x is e.  
The method on page 294 will work if the superclass of e is X. (Because  
that's where the original implementation is defined.) However, this is  
not the case. The superclass of the eigenclass is not the original  
class. It is the eigenclass of the original class. Finally, note that in  
saying "the superclass of the eigenclass is not the original class", it  
would appear that it was at one stage. According to Paolo Nusco  
Perrotta, at least some implementations of 1.8.2 and 1.9 had this  
behaviour:

[http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/248178](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/248178)

(link repeated from my original post).

Regards,

Danny.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Danny\_O\_cuiv](https://avatars.discourse-cdn.com/v4/letter/d/6bbea6/32.png) [@Danny\_O\_cuiv](https://rubytalk.org/u/Danny_O_cuiv)\
**Post date:** [11 May 2009 12:42 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/11 "2009-05-11T12:42:04Z")

</div>

Rick, Robert,

Thanks again for your replies.

Rick wrote:

> If you go in and look at the implementation, you'll find that the  
> eigenclass of String has a superclass slot which points to the  
> eigenclass of Object, but the superclass method implementation skips  
> past 'singleton' classes, until it gets to \<Class:Class\>

To me, that smacks of being ad hoc and inconsistent. The superclass  
method implementation skips past 'singleton' classes, until it gets to  
#\<Class:Class\>. But #\<Class:Class\> is itself a 'singleton' class, so I  
can't see the rationale there. In other words, I can't really grasp what  
semantics are being exposed.

Robert wrote:

> But in reality singleton classes, yes that is what I prefer 😉 are  
> very simple because you really never care too much about their  
> inheritance. The more I work with Ruby the less I care about  
> inheritance in general.

I would disagree that one would never really care too much about an  
eigenclass's inheritance. Example 8-10 on page 294 of the Flanagan/Matz  
book details a very nice-looking technique for doing interception. (The  
particular example uses the technique to wrap tracing code.) This  
technique depends on accessing the original implementation of the method  
by calling super in an eigenclass, so the inheritance of the eigenclass  
is crucial here.

In attempting to understand why this might work, I have four conflicting  
viewpoints. Say I have a class X that I instantiate to get a regular  
object x. Say that the eigenclass of x is e. For the interception  
technique to work, X needs to be above e in the inheritance hierarchy.

(i) The Flanagan/Matz book says that an eigenclass of a regular object  
doesn't have a superclass. (So that e has no superclass.) Clearly this  
is incorrect.

(ii) Exploring using the superclass method gives:  
e.superclass # =\> #\<Class:X\>  
e.superclass.superclass # =\> #\<Class:Class\>  
e.superclass.superclass.superclass # =\> #\<Class:Class\>  
with the same result for any further calls to superclass. This indicates  
that X is not in the inheritance hierarchy of e and consequently the  
technique should not work.

(iii) Exploring using the ancestors method gives:  
e.ancestors # =\> [X, Object, Kernel]  
This indicates that X is in the inheritance hierarchy of e and  
consequently the technique should work.

(iv) Exploring using is\_a?  
x.is\_a? e # =\> true  
This indicates that e is in the inheritance hierarchy of X (i.e. the  
opposite of the previous indication) and consequently the technique  
should not work.

I'd have to confess that this seems like a conceptual mess to me. I  
presume that I'm grasping the wrong end of some stick or other. Can  
anyone help point out what that might be?

Regards,

Danny

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Forum](https://avatars.discourse-cdn.com/v4/letter/f/43a26b/32.png) [@Forum](https://rubytalk.org/u/Forum)\
**Post date:** [8 May 2009 06:45 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/12 "2009-05-08T06:45:42Z")

</div>

It seems that language is very important 🙂 my English and my  
Smalltalk are very far of those of Rick, and I have realized that  
indeed he read very much better what you meant.

However, although I agree that those terms are somehow not defined up  
to the last detail in Ruby, and I have occasionaly explained about it,  
I just wanted to give you a practical example.  
It is very good to have some unbiased views on things.

But in reality singleton classes, yes that is what I prefer 😉 are  
very simple because you really never care too much about their  
inheritance. The more I work with Ruby the less I care about  
inheritance in general.

Cheers  
Robert

> **···**
>
> On Thu, May 7, 2009 at 10:39 PM, Danny O cuiv \<danny.ocuiv@gmail.com\> wrote:
> 
> > Rick, Robert,
> 
> --  
> Si tu veux construire un bateau ...  
> Ne rassemble pas des hommes pour aller chercher du bois, préparer des  
> outils, répartir les tâches, alléger le travail… mais enseigne aux  
> gens la nostalgie de l’infini de la mer.
> 
> If you want to build a ship, don’t herd people together to collect  
> wood and don’t assign them tasks and work, but rather teach them to  
> long for the endless immensity of the sea.
> 
> --  
> Antoine de Saint-Exupéry

---

<div class="post-metadata">

**Author:** ![Forum](https://avatars.discourse-cdn.com/v4/letter/f/43a26b/32.png) [@Forum](https://rubytalk.org/u/Forum)\
**Post date:** [12 May 2009 10:16 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/13 "2009-05-12T10:16:57Z")

</div>

yes but I was talking about the other direction in the inheritance  
tree, the super class of a singleton class is very well defined as the  
class of the singleton's class object's class. Are we cycling here ;)?

Cheers  
Robert

> **···**
>
> On Mon, May 11, 2009 at 2:42 PM, Danny O cuiv \<danny.ocuiv@gmail.com\> wrote:
> 
> > Rick, Robert,
> > 
> > Thanks again for your replies.
> > 
> > Rick wrote:
> > 
> > > If you go in and look at the implementation, you'll find that the  
> > > eigenclass of String has a superclass slot which points to the  
> > > eigenclass of Object, but the superclass method implementation skips  
> > > past 'singleton' classes, until it gets to \<Class:Class\>
> > 
> > To me, that smacks of being ad hoc and inconsistent. The superclass  
> > method implementation skips past 'singleton' classes, until it gets to  
> > #\<Class:Class\>. But #\<Class:Class\> is itself a 'singleton' class, so I  
> > can't see the rationale there. In other words, I can't really grasp what  
> > semantics are being exposed.
> > 
> > Robert wrote:
> > 
> > > But in reality singleton classes, yes that is what I prefer 😉 are  
> > > very simple because you really never care too much about their  
> > > inheritance. The more I work with Ruby the less I care about  
> > > inheritance in general.
> > 
> > I would disagree that one would never really care too much about an  
> > eigenclass's inheritance. Example 8-10 on page 294 of the Flanagan/Matz  
> > book details a very nice-looking technique for doing interception. (The  
> > particular example uses the technique to wrap tracing code.) This  
> > technique depends on accessing the original implementation of the method  
> > by calling super in an eigenclass, so the inheritance of the eigenclass  
> > is crucial here.
> 
> --  
> Si tu veux construire un bateau ...  
> Ne rassemble pas des hommes pour aller chercher du bois, préparer des  
> outils, répartir les tâches, alléger le travail… mais enseigne aux  
> gens la nostalgie de l’infini de la mer.
> 
> If you want to build a ship, don’t herd people together to collect  
> wood and don’t assign them tasks and work, but rather teach them to  
> long for the endless immensity of the sea.
> 
> --  
> Antoine de Saint-Exupéry

---

<div class="post-metadata">

**Author:** ![David\_Flanagan](https://avatars.discourse-cdn.com/v4/letter/d/aca169/32.png) [@David\_Flanagan](https://rubytalk.org/u/David_Flanagan)\
**Post date:** [13 May 2009 22:10 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/14 "2009-05-13T22:10:03Z")

</div>

> Rick, Robert,
> 
> Thanks again for your replies.
> 
> Rick wrote:  
> \> If you go in and look at the implementation, you'll find that the  
> \>eigenclassof String has asuperclassslot which points to the  
> \>eigenclassof Object, but thesuperclassmethod implementation skips  
> \> past 'singleton' classes, until it gets to \<Class:Class\>
> 
> To me, that smacks of being ad hoc and inconsistent. Thesuperclass  
> method implementation skips past 'singleton' classes, until it gets to  
> #\<Class:Class\>. But #\<Class:Class\> is itself a 'singleton' class, so I  
> can't see the rationale there. In other words, I can't really grasp what  
> semantics are being exposed.

The implementation details are leaking. No semantics should be read  
into this, I think.

> I'd have to confess that this seems like a conceptual mess to me. I  
> presume that I'm grasping the wrong end of some stick or other. Can  
> anyone help point out what that might be?

It is a conceptual mess. It seems somewhat clearer, however, with  
Ruby 1.9.

> **···**
>
> On May 11, 5:42 am, Danny O cuiv \<danny.oc...@gmail.com\> wrote:
> 
> > Regards,
> > 
> > Danny
> > 
> > --  
> > Posted viahttp://www.ruby-forum.com/.

---

<div class="post-metadata">

**Author:** ![Forum](https://avatars.discourse-cdn.com/v4/letter/f/43a26b/32.png) [@Forum](https://rubytalk.org/u/Forum)\
**Post date:** [8 May 2009 06:46 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/15 "2009-05-08T06:46:40Z")

</div>

Sorry: occasionally complained

> **···**
>
> On Fri, May 8, 2009 at 8:45 AM, Robert Dober \<robert.dober@gmail.com\> wrote:
> 
> > On Thu, May 7, 2009 at 10:39 PM, Danny O cuiv \<danny.ocuiv@gmail.com\> wrote:
> > 
> > However, although I agree that those terms are somehow not defined up  
> > to the last detail in Ruby, and I have occasionaly explained about it,

---

<div class="post-metadata">

**Author:** ![Danny\_O\_cuiv](https://avatars.discourse-cdn.com/v4/letter/d/6bbea6/32.png) [@Danny\_O\_cuiv](https://rubytalk.org/u/Danny_O_cuiv)\
**Post date:** [12 May 2009 14:38 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/16 "2009-05-12T14:38:50Z")

</div>

Robert Dober wrote:

> the super class of a singleton class is very well defined as the  
> class of the singleton's class object's class.

Robert,

I mustn't be making myself clear.  
I fully agree with your statement above. Because the language can get a  
bit dense, it's probably clearer to adopt a notation (as I did before)  
of a class called X, an instance of X called x and the eigenclass of x  
called e.

The superclass of e is (as you say) the eigenclass of X (i.e.  
#\<Class:X\>). The superclass of this is the eigenclass of class Class  
(i.e. #\<Class:Class\>). No problem with this whatsoever. I wouldn't go so  
far as to say it's well-defined, because it was different in 1.8.2 and  
in some versions of 1.9, but that's a separate issue which we can leave  
to one side.

However, what is clear from the above is that X is not a superclass of  
e. This is a problem for two reasons:

(i) Certain metaprogramming techniques (e.g the one on page 295 or RPL)  
involve calling super in an eigenclass method, with the intention of  
picking up the implementation of the same method in the original class.  
If X is not a superclass of e, this shouldn't work. But it does.

(ii) Calling the ancestors on e gives:  
e.ancestors # =\> [X, Object, Kernel]  
So we have X appearing as an ancestor of e, when it is neither a  
superclass of e nor an included class in e.

Somebody here must have a better handle on this than me. Please chip in  
if you do.

Thanks,

Danny.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Joshua\_Ballanco](https://avatars.discourse-cdn.com/v4/letter/j/d07c76/32.png) [@Joshua\_Ballanco](https://rubytalk.org/u/Joshua_Ballanco)\
**Post date:** [14 May 2009 04:57 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/17 "2009-05-14T04:57:53Z")

</div>

> > Rick, Robert,
> > 
> > Thanks again for your replies.
> > 
> > Rick wrote:
> > 
> > > If you go in and look at the implementation, you'll find that the  
> > > eigenclassof String has asuperclassslot which points to the  
> > > eigenclassof Object, but thesuperclassmethod implementation skips  
> > > past 'singleton' classes, until it gets to \<Class:Class\>
> > 
> > To me, that smacks of being ad hoc and inconsistent. Thesuperclass  
> > method implementation skips past 'singleton' classes, until it gets to  
> > #\<Class:Class\>. But #\<Class:Class\> is itself a 'singleton' class, so I  
> > can't see the rationale there. In other words, I can't really grasp what  
> > semantics are being exposed.
> 
> The implementation details are leaking. No semantics should be read  
> into this, I think.
> 
> > I'd have to confess that this seems like a conceptual mess to me. I  
> > presume that I'm grasping the wrong end of some stick or other. Can  
> > anyone help point out what that might be?
> 
> It is a conceptual mess. It seems somewhat clearer, however, with  
> Ruby 1.9.

I agree completely. In fact, beyond implementation detail, is there any reason that eigenclasses exist in their semi-privileged realm? For example, I've never completely understood why the following shouldn't work:

\>\> class Test  
\>\> def eigenclass  
\>\> class\<\<self  
\>\> self  
\>\> end  
\>\> end  
\>\> end  
=\> nil  
\>\> TestSubEigen = Class.new(Test.new.eigenclass)  
TypeError: can't make subclass of virtual class  
&nbsp;&nbsp;from (irb):43:in `initialize'  
&nbsp;&nbsp;from (irb):43:in `new'  
&nbsp;&nbsp;from (irb):43

In fact, it seems like the existence of eigenclasses is, to begin with, an implementation detail. As it turns out, they can be very handy for implementing instance-specific methods, but then isn't that the point of a Prototype inheritance model?

Personally, I would like to see Ruby 2.0 formalize Ruby's prototyping abilities. The semantics of "Test.new" could remain the same and be conceptually identical to "Test.prototype.prototype". That is, eigenclasses would be prototype objects that sit between the object and its parent class object. This would have the added benefit of clearing up the method call chain concept, as it would simply follow the trail of prototypes.

Just ideas...

Cheers,

Josh

> **···**
>
> On May 13, 2009, at 6:10 PM, David Flanagan wrote:
> 
> > On May 11, 5:42 am, Danny O cuiv \<danny.oc...@gmail.com\> wrote:

---

<div class="post-metadata">

**Author:** ![Jorg\_W\_Mittag2](https://avatars.discourse-cdn.com/v4/letter/j/e79b87/32.png) [@Jorg\_W\_Mittag2](https://rubytalk.org/u/Jorg_W_Mittag2)\
**Post date:** [15 May 2009 00:20 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/18 "2009-05-15T00:20:02Z")

</div>

Robert Dober wrote:

> However, although I agree that those terms are somehow not defined up  
> to the last detail in Ruby, and I have occasionaly explained about it,

You mean "complained", right? Yes, it is kind of unfortunate, that we  
ended up with this confusion. I would like to point out, however, that  
this is basically a historical accident, and not anybody's (certainly  
not matz's) fault.

The fundamental problem is that matz has always refused (and still  
refuses) to pick a name. And over time he has done that for two  
different reasons. Originally, he considered singleton classes to be a  
private implementation detail of MRI, and he envisioned that there  
would be other implementations that would choose to implement  
singleton methods differently. He wanted to have per-object methods,  
and he needed something to store them in, so he chose something that  
was \*already\* supported by MRI: a class. Additionally, this meant that  
he needed exactly 0 changes to the method resolution algorithm, and  
only one single if-condition in the superclass algorithm. \*And\* he  
could reuse that same solution for mixins.

Unfortunately, that supposedly private implementation was leaked to  
the programmer, exactly \*because\* the singleton class is "just a  
class". Due to the way class bodies work (namely that they return the  
value of the last expression inside the body instead of the class  
object, and that self is bound to the class object), you can get  
access to the singleton class with the 'class \<\< self; self end' trick  
(or its equivalent).

As soon as you can get access to something, you need to name it. And  
people did. They named it singleton class, eigenclass, virtual class,  
hidden class, metaclass and dozens more ...

Which brings us to the present. \*Now\* matz refuses to pick a name,  
because he doesn't want to ... well, \*pick\* a name. He wants the  
\*community\* to pick a name, and he will simply approve whatever we  
come up with. What it boils down to is that he does \*not\* consider  
himself a "benevolent dictator", but more a "benevolent chairman" who  
does not himself make decisions, but rather tries to "milk" a  
consensus out of a very diverse group of very opinionated people, just  
like a chairman of a senate committee would (well, at least in an  
ideal world where neither the members nor the chairman are corrupt or  
in any way influenced by lobbyists).

Currently, singleton class, eigenclass and metaclass are still in the  
race. I agree that metaclass is wrong, but since it is the name used  
by \_why the lucky stiff in what is probably one of the best  
introductory texts about the more esoteric corners of Ruby's object  
system, a lot of Rubyists learn that name, so it is going to stick  
with us. Of the other two I prefer eigenclass, both to avoid the  
confusion with the singleton pattern and because it nicely fits in  
with the already existing usages in mathematics (eigenvalue,  
eigenvector, eigenspace, eigenmode, eigenfrequency, eigenstate,  
eigenspectrum, eigenfunction, eigendecomposition, eigenproblem) and  
computer science (eigenface, eigenratio).

jwm

---

<div class="post-metadata">

**Author:** ![Gary\_Wright](https://avatars.discourse-cdn.com/v4/letter/g/58956e/32.png) [@Gary\_Wright](https://rubytalk.org/u/Gary_Wright)\
**Post date:** [12 May 2009 16:02 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/19 "2009-05-12T16:02:15Z")

</div>

I think you need to decouple the inheritance relationships (what superclass reveals) from the method lookup chain (what ancestor partially reveals) in order to understand the semantics. Arguably this could all be clearer via some better naming.

Confusion comes from:  
-- the super keyword uses the method lookup chain, not the superclass chain  
-- the ancestor method reports on the method lookup chain, not the inheritance chain  
-- the ancestor method doesn't show eigenclasses, they are implied

> **···**
>
> On May 12, 2009, at 10:38 AM, Danny O cuiv wrote:
> 
> > However, what is clear from the above is that X is not a superclass of  
> > e. This is a problem for two reasons:
> > 
> > (i) Certain metaprogramming techniques (e.g the one on page 295 or RPL)  
> > involve calling super in an eigenclass method, with the intention of  
> > picking up the implementation of the same method in the original class.  
> > If X is not a superclass of e, this shouldn't work. But it does.
> > 
> > (ii) Calling the ancestors on e gives:  
> > e.ancestors # =\> [X, Object, Kernel]  
> > So we have X appearing as an ancestor of e, when it is neither a  
> > superclass of e nor an included class in e.
> > 
> > Somebody here must have a better handle on this than me. Please chip in  
> > if you do.

---

<div class="post-metadata">

**Author:** ![Jorg\_W\_Mittag2](https://avatars.discourse-cdn.com/v4/letter/j/e79b87/32.png) [@Jorg\_W\_Mittag2](https://rubytalk.org/u/Jorg_W_Mittag2)\
**Post date:** [15 May 2009 00:25 UTC](https://rubytalk.org/t/superclass-of-eigenclass/53284/20 "2009-05-15T00:25:01Z")

</div>

Joshua Ballanco wrote:

> In fact, it seems like the existence of eigenclasses is, to begin  
> with, an implementation detail.

Originally, they were.

> As it turns out, they can be very  
> handy for implementing instance-specific methods,

Exactly. It is my understanding that they were only added as a place  
to "stick" per-object methods. MRI already had classes, so why not use  
them? If you stick per-object methods in an eigenclass you need  
exactly 0 new constructs in the interpreter, 0 changes to method  
lookup and just one if-condition in superclass lookup. Plus, you can  
also implement mixins the same way. That's a \*lot\* of leverage for  
essentially one line of code.

AFAIK, the fact that they were exposed to the programmer is more of an  
accident than a well-designed thought-out language feature.

jwm

[Next page](https://rubytalk.org/t/superclass-of-eigenclass/53284.md?page=2)
