From: Robert Klemme Date: 2007-12-16T21:24:58+09:00 Subject: Re: Inheritance and meta-classes On 13.12.2007 15:33, Rick DeNatale wrote: > On 12/13/07, Robert Klemme 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 > => #> > irb(main):007:0> Array.meta > => # > irb(main):008:0> Array.meta.superclass > => # > irb(main):009:0> Array.meta.superclass.superclass > => # Ah, now I see! Should've put on my glasses. ;-) >> 2007/12/13, Adam Salter : >>> 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 >> => # >> 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 >> => # >> irb(main):005:0> c2.x >> => "X" >> irb(main):006:0> c2.ancestors >> => [#, #, Object, Kernel] >> irb(main):007:0> c1.class.instance_methods.grep /x/ >> => ["extend"] >> irb(main):008:0> class <> => ["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< Here's a simplified diagram > 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 => # irb(main):002:0> def o.xxx;1;end => nil irb(main):003:0> o.xxx => 1 irb(main):004:0> class < ["xxx"] irb(main):005:0> o1 = o.clone => # irb(main):006:0> o1.xxx => 1 irb(main):007:0> class < ["xxx"] irb(main):008:0> o2 = o.dup => # irb(main):009:0> o2.xxx NoMethodError: undefined method `xxx' for # from (irb):9 from :0 irb(main):010:0> class < [] Kind regards robert