Superclass of eigenclass


#1

On page 261 of The Ruby P.ming 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):

irb> greeting = “hello”
=> “hello”
irb> greeting.eigenclass
=> #<Class:#String:0xb7cf5a14>
irb> 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


#2

On Thu, May 7, 2009 at 8:35 AM, Danny O cuiv removed_email_address@domain.invalid
wrote:

On page 261 of The Ruby P.ming 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
p ancestors
end
[A, Object, Kernel]

class A
f = class << self; self; end
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]


#3

On Thu, May 7, 2009 at 8:35 AM, Danny O cuiv removed_email_address@domain.invalid
wrote:

On page 261 of The Ruby P.ming 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.

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.


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale


#4

On Thu, May 7, 2009 at 11:50 AM, Rick DeNatale removed_email_address@domain.invalid
wrote:

On Thu, May 7, 2009 at 8:35 AM, Danny O cuiv removed_email_address@domain.invalid wrote:

On page 261 of The Ruby P.ming 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.

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
def eigenclass
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/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale


#5

On Thu, May 7, 2009 at 1:17 PM, Danny O cuiv removed_email_address@domain.invalid
wrote:

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.


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale


#6

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


#7

On Thu, May 7, 2009 at 7:17 PM, Danny O cuiv removed_email_address@domain.invalid
wrote:

following:
the eigenclass.)
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
from (irb):9:in new' from (irb):9 from /usr/local/bin/irb:12:in

Cheers
R.


#8

Rick, Robert,

Thanks for your helpful replies. I have just introduced myself to Ruby
in the last couple of weeks by reading The Ruby P.ming 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:

irb> a.instance_of? s
=> false
irb> 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

(link repeated from my original post).

Regards,

Danny.


#9

On Fri, May 8, 2009 at 8:45 AM, Robert D. removed_email_address@domain.invalid
wrote:

On Thu, May 7, 2009 at 10:39 PM, Danny O cuiv removed_email_address@domain.invalid 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,
Sorry: occasionally complained


#10

On Thu, May 7, 2009 at 10:39 PM, Danny O cuiv removed_email_address@domain.invalid
wrote:

Rick, Robert,
It seems that language is very important :slight_smile: 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 :wink: 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

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.


#11

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


#12

Robert D. 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.


#13

On Mon, May 11, 2009 at 2:42 PM, Danny O cuiv removed_email_address@domain.invalid
wrote:

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

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.


#14

Gary W. wrote:

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

Aaaah! The penny finally drops! Thanks a million for this, Gary. I think
I’d have been banging my head against a brick wall for ages without your
explanation.

I’d probably still stand by my earlier assertion that it’s a conceptual
mess, however. It’s just that now that I know what the semantics really
are, I can work with it. Bad naming trips up even very experienced
people. For example, in RPL, no lesser luminaries than David Flanagan
and Matz write on page 238 that super “invokes a method with the same
name as the current one, in the superclass of the current class”. Given
your first point above, it’s clear that this is not just misleading,
it’s also Just Plain Wrong ™.

That said, for my own purposes, I now have a pretty good picture of the
semantics (naming snafus and all) and can definitely work with that
picture. So thanks again.

Regards,

Danny


#15

On May 12, 2009, at 10:38 AM, Danny O cuiv wrote:

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

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


#16

On May 7, 5:35 am, Danny O cuiv removed_email_address@domain.invalid wrote:

On page 261 of The Ruby P.ming 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:

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:

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.


#17

On May 11, 5:42 am, Danny O cuiv removed_email_address@domain.invalid wrote:

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.


#18

On May 7, 9:21 am, Rick DeNatale removed_email_address@domain.invalid wrote:

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.

David Flanagan

#19

On May 13, 2009, at 6:20 PM, David Flanagan wrote:

On May 12, 9:29 am, Danny O cuiv removed_email_address@domain.invalid wrote:

Gary W. wrote:

Confusion comes from:
– the super keyword uses the method lookup chain, not thesuperclass
chain
– the ancestor method reports on the method lookup chain, not the
inheritance chain

I have to disagree with Gary’s nomenclature.

No problem. I just made them up for that post.

Inheritance and method
lookup are basically the same thing, so trying to distinguish “method
lookup chain” from “inheritance chain” is hard to do.

But since they are only ‘basically the same’ and not exactly the same
it is important to distinguish between them. This is more important in
1.8.X than in 1.9.X since in 1.9.X ‘superclass’ tracks the method
lookup chain more closely. In 1.8.X ‘superclass’ is pretty hard to
explain when you try to include singleton classes.

Maybe we can say “class hierarchy” when we want to exclude modules
as the
superclass method does and “method inheritance chain” (or something)
when we want to include modules.

I could quibble with those definitions, but my main point was that
‘ancestors’ doesn’t match the ‘superclass chain’ (because of modules)
nor does it always match the ‘method lookup chain’ (because of
eigenclasses).

Gary W.


#20

On May 12, 9:29 am, Danny O cuiv removed_email_address@domain.invalid wrote:

Gary W. wrote:

Confusion comes from:
– the super keyword uses the method lookup chain, not thesuperclass
chain
– the ancestor method reports on the method lookup chain, not the
inheritance chain

I have to disagree with Gary’s nomenclature. Inheritance and method
lookup are basically the same thing, so trying to distinguish “method
lookup chain” from “inheritance chain” is hard to do. Maybe we can
say “class hierarchy” when we want to exclude modules as the
superclass method does and “method inheritance chain” (or something)
when we want to include modules.

Aaaah! The penny finally drops! Thanks a million for this, Gary. I think
I’d have been banging my head against a brick wall for ages without your
explanation.

I’d probably still stand by my earlier assertion that it’s a conceptual
mess, however. It’s just that now that I know what the semantics really
are, I can work with it. Bad naming trips up even very experienced
people. For example, in RPL, no lesser luminaries than David Flanagan
and Matz write on page 238 that super “invokes a method with the same
name as the current one, in thesuperclassof the current class”.

You’re right. I should have said something like “in the nearest
ancestor of the current class” or something to that effect, so that
modules are included. I may also want to update this paragraph to
point out that a singleton method of an object can chain to a regular
instance method of the object.

Thanks for pointing out this error!