From: Rick DeNatale Date: 2007-05-25T03:39:26+09:00 Subject: Re: virtual metaclasses explanation On 5/24/07, angel.of.north@googlemail.com wrote: > I am getting a bit weighed down at this moment by looking under the > bonnet a bit too much, but in figure 24.2 in Dave Thomas Pragmatic > Programming, > classes and objects is is unclear how the metaclass acquires its > additional method as strings. > Dave Rhomas says that the metaclass will inherit all it methods from > its corresponding proper class. I don't have the time to digest your long thread which followed, but I'll try to address these questions. > 1. Do all inheritance chains and all objects have a homologue > metaclass at all times, which are behind the scenes? In ruby metaclasses are singleton classes of classes. Just as a class holds the table used to find the methods of its instances, the metaclass holds the table used to find methods for its sole instance i.e. the class. The singleton class which serves as the metaclass of a class is created when the class is created. This is done internally by the Ruby interpreter. While object's don't have metaclasses they can have singleton classes, which are created when needed, e.g. when you do something like a = "abc" b = "def" def a.method;...;end # singleton class for the object referenced by a is created now class < 2. Do a chain of metaclasses spontaneously appear at the moment > when a class is used as a receiver : so to be used to call a method > inside of a parentclass? No, as I just said, metaclasses are created along with their corresponding class. The metaclass' superclass is set to the metaclass of the classes superclass. This is one difference between singleton classes of objects and singleton classes used as metaclasses. The later can have subclasses, while the former cannot. Normal object singleton classes have their internal superclass set to the original class of the object. Note that I'm using superclass and class here to describe the internal relationship. Ruby's class and superclass methods don't always give a true picture when singleton/metaclasses are involved. I personally think of the class-like objects linked together with the superclass field as a behavior chain since it's used to implement the behaviour of one or more objects. > 3. How can a metaclass contain more methods than its corresponding > class has. Can you give an example of the code in the next addition? The number of methods in the class and the number of methods in the metaclass is completely independent, for example, look at the following and compare it to what I said in reponse to question #1 class MyClass def initialize # This defines the initialize method in MyClass which # Like all such methods are available to INSTANCEs # of the class, and its subclasses # end def method1 # another instance method end def MyClass.class_method # This defines a class method in the # singleton class of MyClass (i.e. the metaclass) # which is available to instances of the metaclass and # its subclasses end def self.class_method_2 # This adds another class method, it's # Just a different syntax for the last form of definition # since within the scope of a class definition, self is # bound to that class end class << self # or equivalently class << MyClass # Now we are in an inner scope, that of MyClass' metaclass def class_method_3 # So this also becomes a class method # of MyClass end end So MyClass has two instance methods (plus what it inherits from Object) and three class methods (plus what the metaclass inherits from Object's metaclass. As a related note, when a class includes a Module, another kind of virtual class is inserted between the class and it's superclass. This virtual class (or I_Class) looks like a class but has a pointer to the method table of the module instead of having its own table. This lets modules appear in different behavior chains and lets those including them see updates to the module when they are made. There are some other fields of the module which are also copied, but I'm not going to mention them here since they aren't relevant and might confuse. > 4. Which is searched first in the inheritance chain. methods in > the proper parents, or methods in the meta parents? There's no cross over at all. When finding a method for an object, Ruby gets the head of what I called the behavior chain. For a normal object with no singleton class, this will be the class, For an object with a singleton class this will be the singleton class. If the method is found, then it's used, if not the next class-like thing in the behavior chain is examined and so forth. The keyword super makes the search start in the next link in the behavior chain after the one in which the current method was found. So if you're invoking a method on a normal object, no metaclasses will be on the chain. If you are invoking a method on a class, then the behavior chain will consist of metaclasses, except that the superclass of Object's metaclass is Class. If you think about this hard enough it makes sense, since the instance methods of Class are for use by classes. So if we have class B ... end b = B.new b.to_s The search goes: B -> Object -> (I_Class wrapper for Kernel) the last is because Object includes Kernel and B.new the search goes (singleton of B) -> (singleton of Object) -> Class -> Module -> Object -> (I_Class wrapper for Kernel) > 5. If a method is found is the search stopped even though another > method with the same name might exist in a parallel chain? As I just described, the parallel chain is irrelevant, it isn't considered at all. HTH -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/