# Inheritance and meta-classes

**URL:** <https://www.ruby-forum.com/t/inheritance-and-meta-classes/122953>\
**Category:** Ruby\
**Created:** [December 13, 2007, 12:17am UTC](https://www.ruby-forum.com/t/inheritance-and-meta-classes/122953 "2007-12-13T00:17:21Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![asetzler](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ac91a4/32.png) [@asetzler](https://www.ruby-forum.com/u/asetzler)\
**Post date:** [December 13, 2007, 12:17am UTC](https://www.ruby-forum.com/t/inheritance-and-meta-classes/122953/1 "2007-12-13T00:17:21Z")

</div>

Hi all,

OK. I’m trying to work out where a method is defined in Rails.  
It’s in a test, and the specific function that’s being called is  
‘post’, but my question is not a Rails question, it’s Ruby.

How do I find where a function is defined in the inheritance tree?  
Because of metaclass inheritance being cyclical I don’t know where to  
stop looking.

I made the following as a test but I still can’t find the function  
being called so I’m guessing I’m missing some of the inheritance tree…

module Debugs  
def find\_respond\_to\_in\_class\_heirarchy(obj, method)  
if obj.respond\_to?(:superclass)  
arr = find\_respond\_to\_in\_class\_heirarchy(obj.superclass, method)  
arr.unshift([obj.class.respond\_to?(method),  
obj.metaclass.respond\_to?(method), obj.superclass.respond\_to?(method)])  
elsif obj.nil?  
arr = [[nil.class.respond\_to?(method), nil.metaclass.respond\_to?  
(method), NoMethodError]]  
else  
arr = find\_respond\_to\_in\_class\_heirarchy(obj.class, method)  
arr.unshift([obj.class.respond\_to?(method),  
obj.metaclass.respond\_to?(method), NoMethodError])  
end  
arr  
end  
end

class Object  
include Debugs  
def metaclass  
class \<\< self  
self  
end  
end  
end

Wow this whole metaclass, class, object, module relationship is pretty  
mindbending…

Cheers,  
-Adam

---

<div class="post-metadata">

**Author:** ![asetzler](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ac91a4/32.png) [@asetzler](https://www.ruby-forum.com/u/asetzler)\
**Post date:** [December 13, 2007, 6:01am UTC](https://www.ruby-forum.com/t/inheritance-and-meta-classes/122953/2 "2007-12-13T06:01:01Z")

</div>

Any suggestions?  
(or has the subject been done to death…)

I still don’t get how you can query and see where in the chain a  
method got added to an object…

I’ve now found that you can do:  
obj.class.ancestors # =\> Array

But that still doesn’t include metaclasses…

How does Ruby know??

---

<div class="post-metadata">

**Author:** ![asetzler](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ac91a4/32.png) [@asetzler](https://www.ruby-forum.com/u/asetzler)\
**Post date:** [December 13, 2007, 3:38pm UTC](https://www.ruby-forum.com/t/inheritance-and-meta-classes/122953/3 "2007-12-13T15:38:00Z")

</div>

On 12/13/07, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > How do I find where a function is defined in the inheritance tree?  
> > > Because of metaclass inheritance being cyclical I don’t know where  
> > > to stop looking.
> 
> Where exactly do you see cycles? I am not aware of any.

shadowfax:~/ssanta rick$ irb  
irb(main):001:0\> def meta  
irb(main):002:1\> class \<\< self  
irb(main):003:2\> self  
irb(main):004:2\> end  
irb(main):005:1\> end  
=\> nil  
irb(main):006:0\> meta  
=\> #\<Class:#Object:0x349a4\>  
irb(main):007:0\> Array.meta  
=\> #Class:Array  
irb(main):008:0\> Array.meta.superclass  
=\> #Class:Class  
irb(main):009:0\> Array.meta.superclass.superclass  
=\> #Class:Class

> =\> “X”  
> irb(main):004:0\> c2 = Class.new c1  
> =\> #Class:0x7ff8f4b0  
> irb(main):005:0\> c2.x  
> =\> “X”  
> irb(main):006:0\> c2.ancestors  
> =\> [#Class:0x7ff8f4b0, #Class:0x7ff9f70c, Object, Kernel]  
> irb(main):007:0\> c1.class.instance\_methods.grep /x/  
> =\> [“extend”]  
> irb(main):008:0\> class \<\<c2;self end.instance\_methods.grep /x/  
> =\> [“x”, “extend”]

I don’t see any metaclasses here. c1 and c2 are simply anonymous  
classes.

A metaclass doesn’t sit between an instance and its class. A singleton  
class of an instance would, but that’s not a metaclass (although the  
way the two terms get conflated I can see where that’s a common  
misconception). A metaclass is a singleton ‘class’ which holds the  
behavior of a class.

Here’s a simplified diagram  
[http://myskitch.com/rubyredrick/skitched-20071213-093049/](http://myskitch.com/rubyredrick/skitched-20071213-093049/)

It’s simplified since it doesn’t include the inclusion of Kernel by  
Object.

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![asetzler](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ac91a4/32.png) [@asetzler](https://www.ruby-forum.com/u/asetzler)\
**Post date:** [December 13, 2007, 12:01pm UTC](https://www.ruby-forum.com/t/inheritance-and-meta-classes/122953/4 "2007-12-13T12:01:55Z")

</div>

> > How do I find where a function is defined in the inheritance tree?  
> > Because of metaclass inheritance being cyclical I don’t know where  
> > to stop looking.

Where exactly do you see cycles? I am not aware of any.

2007/12/13, Adam S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> I still don’t get how you can query and see where in the chain a  
> method got added to an object…
> 
> I’ve now found that you can do:  
> obj.class.ancestors # =\> Array
> 
> But that still doesn’t include metaclasses…

Correct.

> How does Ruby know??

The meta class is there but it’s hidden from #ancestors as you found  
out. Inheritance wise it sits between an object and its class.

irb(main):001:0\> c1 = Class.new  
=\> #Class:0x7ff9f70c  
irb(main):002:0\> def c1.x; “X” end  
=\> nil  
irb(main):003:0\> c1.x  
=\> “X”  
irb(main):004:0\> c2 = Class.new c1  
=\> #Class:0x7ff8f4b0  
irb(main):005:0\> c2.x  
=\> “X”  
irb(main):006:0\> c2.ancestors  
=\> [#Class:0x7ff8f4b0, #Class:0x7ff9f70c, Object, Kernel]  
irb(main):007:0\> c1.class.instance\_methods.grep /x/  
=\> [“extend”]  
irb(main):008:0\> class \<\<c2;self end.instance\_methods.grep /x/  
=\> [“x”, “extend”]

Note also that #respond\_to? is a weak method to determine whether an  
instance will respond to a method, because of #method\_missing which I  
believe is used a lot by Rails. Also, it is not called on the class  
but on the object.

You can use #instance\_method(s) to check whether a class implements a  
certain instance method but as I said, you might not be lucky.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![asetzler](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ac91a4/32.png) [@asetzler](https://www.ruby-forum.com/u/asetzler)\
**Post date:** [December 16, 2007, 1:25pm UTC](https://www.ruby-forum.com/t/inheritance-and-meta-classes/122953/5 "2007-12-16T13:25:56Z")

</div>

On 13.12.2007 15:33, Rick DeNatale wrote:

> irb(main):004:2\> end  
> irb(main):005:1\> end  
> =\> nil  
> irb(main):006:0\> meta  
> =\> #\<Class:#Object:0x349a4\>  
> irb(main):007:0\> Array.meta  
> =\> #Class:Array  
> irb(main):008:0\> Array.meta.superclass  
> =\> #Class:Class  
> irb(main):009:0\> Array.meta.superclass.superclass  
> =\> #Class:Class

Ah, now I see! Should’ve put on my glasses. 😉

> > > How does Ruby know??  
> > > =\> #Class:0x7ff8f4b0  
> > > irb(main):005:0\> c2.x  
> > > =\> “X”  
> > > irb(main):006:0\> c2.ancestors  
> > > =\> [#Class:0x7ff8f4b0, #Class:0x7ff9f70c, Object, Kernel]  
> > > irb(main):007:0\> c1.class.instance\_methods.grep /x/  
> > > =\> [“extend”]  
> > > irb(main):008:0\> class \<\<c2;self end.instance\_methods.grep /x/  
> > > =\> [“x”, “extend”]
> 
> I don’t see any metaclasses here. c1 and c2 are simply anonymous classes.

According to the definition given by you the class that’s used in  
statement 8 is a meta class.

> A metaclass doesn’t sit between an instance and its class. A singleton  
> class of an instance would, but that’s not a metaclass (although the

Since a metaclass - according to your definition - is a class’s  
singleton class it sits between the instance (the class object, e.g.  
Array) and its class (Class) in the same way an ordinary’s object’s  
singleton class does - which is also shown by the image you referred to  
in your posting.

> way the two terms get conflated I can see where that’s a common  
> misconception). A metaclass is a singleton ‘class’ which holds the  
> behavior of a class.

You mean “class\<\<Array;self;end”, do you?

> Here’s a simplified diagram  
> [http://myskitch.com/rubyredrick/skitched-20071213-093049/](http://myskitch.com/rubyredrick/skitched-20071213-093049/)
> 
> It’s simplified since it doesn’t include the inclusion of Kernel by Object.

Nice colors. 😉 I reckon Array’ is intended to mean the singleton  
class of object Array. I am not sure I get your point where you wanted  
to correct me. As far as I can see we are completely in sync.

Generally singleton classes of class instances and of ordinary instances  
behave the same. The only difference I can see so far is that, since  
classes can inherit from each other, a subclass also shares instance  
methods defined for its superclass (see my irb session). Btw, something  
similar happens with instances when cloned:

irb(main):001:0\> o = Object.new  
=\> #Object:0x7ff9e474  
irb(main):002:0\> def o.xxx;1;end  
=\> nil  
irb(main):003:0\> o.xxx  
=\> 1  
irb(main):004:0\> class \<\<o;self;end.instance\_methods.grep /xx/  
=\> [“xxx”]  
irb(main):005:0\> o1 = o.clone  
=\> #Object:0x7ff80eec  
irb(main):006:0\> o1.xxx  
=\> 1  
irb(main):007:0\> class \<\<o1;self;end.instance\_methods.grep /xx/  
=\> [“xxx”]  
irb(main):008:0\> o2 = o.dup  
=\> #Object:0x7ff73cec  
irb(main):009:0\> o2.xxx  
NoMethodError: undefined method `xxx’ for #Object:0x7ff73cec  
from (irb):9  
from :0  
irb(main):010:0\> class \<\<o2;self;end.instance\_methods.grep /xx/  
=\> []

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![asetzler](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ac91a4/32.png) [@asetzler](https://www.ruby-forum.com/u/asetzler)\
**Post date:** [December 17, 2007, 4:51pm UTC](https://www.ruby-forum.com/t/inheritance-and-meta-classes/122953/6 "2007-12-17T16:51:39Z")

</div>

On 12/16/07, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On 13.12.2007 15:33, Rick DeNatale wrote:

> > Here’s a simplified diagram  
> > [http://myskitch.com/rubyredrick/skitched-20071213-093049/](http://myskitch.com/rubyredrick/skitched-20071213-093049/)
> > 
> > It’s simplified since it doesn’t include the inclusion of Kernel by Object.
> 
> Nice colors. 😉 I reckon Array’ is intended to mean the singleton  
> class of object Array. I am not sure I get your point where you wanted  
> to correct me. As far as I can see we are completely in sync.

Yes I copied the classname’ notation from the diagrams Dave T.  
uses in the pickaxe.

The statement I wanted to correct, maybe I misunderstood it was:

> The meta class is there but it’s hidden from #ancestors as you found  
> out. Inheritance wise it sits between an object and its class.

I read object as an instance of “its class.” The above statement is  
wrong in two regards.

First, the metaclass isn’t on the inheritance chain of the instance,  
it’s on the inheritance chain of the class, but that’s a horse of a  
different color.

Second, in the klass chain it’s on the other side of the class, it goes:

instance - klass-\> class -klass-\> class’

NOT

instance -klass-\> class’ -klass-\> class

> irb(main):003:0\> o.xxx  
> =\> #Object:0x7ff73cec  
> irb(main):009:0\> o2.xxx  
> NoMethodError: undefined method `xxx’ for #Object:0x7ff73cec  
> from (irb):9  
> from :0  
> irb(main):010:0\> class \<\<o2;self;end.instance\_methods.grep /xx/  
> =\> []

Not quite the same, what happens here is that cloning an object with a  
singleton class gives the clone a singleton class which looks like the  
original object’s singleton class:

k$ irb  
irb(main):001:0\> def meta  
irb(main):002:1\> class \<\< self;self;end  
irb(main):003:1\> end  
=\> nil  
irb(main):004:0\> o = Object.new  
=\> #Object:0x89724  
irb(main):005:0\> o.meta  
=\> #\<Class:#Object:0x89724\>  
irb(main):006:0\> o1 = o.clone  
=\> #Object:0x82c44  
irb(main):007:0\> o1.meta  
=\> #\<Class:#Object:0x82c44\>  
irb(main):008:0\> o.meta == o1.meta  
=\> false

One last point, you have to be careful in looking at the results from  
experiments like this in irb/ruby programs because some of the  
reflection methods in ruby deliberately lie about what’s really  
happening under the covers.

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![asetzler](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ac91a4/32.png) [@asetzler](https://www.ruby-forum.com/u/asetzler)\
**Post date:** [December 17, 2007, 5:52pm UTC](https://www.ruby-forum.com/t/inheritance-and-meta-classes/122953/7 "2007-12-17T17:52:03Z")

</div>

On 12/17/07, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 2007/12/17, Rick DeNatale [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> > The statement I wanted to correct, maybe I misunderstood it was:
> > 
> > > The meta class is there but it’s hidden from #ancestors as you found  
> > > out. Inheritance wise it sits between an object and its class.
> > 
> > I read object as an instance of “its class.” The above statement is  
> > wrong in two regards.
> 
> But note that any class is also an instance.

But that doesn’t seem to be relevant to the 'slightly restated assertion  
that.

Inheritance wise the metaclass sits between an object and its class.

Let’s say that the object is an array, we have

array -klass-\> Array -\>klass-\> Array’ (i.e. Arrays metaclass)

which isn’t an inheritance chain anyway, but it illustrates that the  
metaclass doesn’t sit between an instance and its class. Now lets’  
say the object was a class, say Array

we have two parallel inheritance chains:

Array Array’  
| |  
super super  
V V  
Object Object’

> Again, since a class is also an instance I choose to use the more  
> general term. But the statement holds true for classes as well because  
> with regard to this there is no difference between an ordinary  
> instance and an instance of Class (or Module for that matter). There  
> is in fact some difference in behavior that results from this (see my  
> posting) but the singleton class of a class sits between the instance  
> (the class) and its class (Class).

Yes, but not all singleton classes are metaclasses, I maintain that  
only singleton classes of classes are properly called metaclasses.  
The meaning of metaclass is “class of a class”, so calling the  
singleton class of a non-class object a metaclass is a misnomer,  
albeit, sadly, a common one.

Given this definition, it only holds true if the object in the general  
statement is a class which makes the statement incorrect in general.

> > > Generally singleton classes of class instances and of ordinary instances  
> > > behave the same. The only difference I can see so far is that, since  
> > > classes can inherit from each other, a subclass also shares instance  
> > > methods defined for its superclass (see my irb session). Btw, something  
> > > similar happens with instances when cloned:

> > Not quite the same, what happens here is that cloning an object with a  
> > singleton class gives the clone a singleton class which looks like the  
> > original object’s singleton class:

> That’s why I wrote “similar” and not “same”…

The point is that there’s no inheritance involved, just copying.

> > One last point, you have to be careful in looking at the results from  
> > experiments like this in irb/ruby programs because some of the  
> > reflection methods in ruby deliberately lie about what’s really  
> > happening under the covers.
> 
> Can you elaborate which methods do actually lie?

Off the top of my head, ancestors for one.

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![asetzler](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ac91a4/32.png) [@asetzler](https://www.ruby-forum.com/u/asetzler)\
**Post date:** [December 17, 2007, 5:14pm UTC](https://www.ruby-forum.com/t/inheritance-and-meta-classes/122953/8 "2007-12-17T17:14:34Z")

</div>

2007/12/17, Rick DeNatale [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> > to correct me. As far as I can see we are completely in sync.  
> > wrong in two regards.  
> > But note that any class is also an instance.

> First, the metaclass isn’t on the inheritance chain of the instance,  
> it’s on the inheritance chain of the class, but that’s a horse of a  
> different color.

Again, since a class is also an instance I choose to use the more  
general term. But the statement holds true for classes as well because  
with regard to this there is no difference between an ordinary  
instance and an instance of Class (or Module for that matter). There  
is in fact some difference in behavior that results from this (see my  
posting) but the singleton class of a class sits between the instance  
(the class) and its class (Class).

> Second, in the klass chain it’s on the other side of the class, it goes:
> 
> instance - klass-\> class -klass-\> class’
> 
> NOT
> 
> instance -klass-\> class’ -klass-\> class

Do I understand you properly that you claim the chain is

Array → Class → Array’

If so, I strongly believe you are wrong. It’s

Array → Array’ → Class

Or did you mean

anArray → Array → Array’

Where Array’ is the singleton class of Array like in

irb(main):001:0\> c=class \<\<Array;self;end  
=\> #Class:Array

This is correct.

> > irb(main):003:0\> o.xxx  
> > =\> #Object:0x7ff73cec  
> > irb(main):009:0\> o2.xxx  
> > NoMethodError: undefined method `xxx’ for #Object:0x7ff73cec  
> > from (irb):9  
> > from :0  
> > irb(main):010:0\> class \<\<o2;self;end.instance\_methods.grep /xx/  
> > =\> []
> 
> Not quite the same, what happens here is that cloning an object with a

That’s why I wrote “similar” and not “same”…

> singleton class gives the clone a singleton class which looks like the  
> original object’s singleton class:

> One last point, you have to be careful in looking at the results from  
> experiments like this in irb/ruby programs because some of the  
> reflection methods in ruby deliberately lie about what’s really  
> happening under the covers.

Can you elaborate which methods do actually lie?

Cheers

robert
