Virtual metaclasses explanation

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

  1. Do all inheritance chains and all objects have a homologue
    metaclass at all times, which are behind the scenes?
  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?
  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?
  4. Which is searched first in the inheritance chain. methods in
    the proper parents, or methods in the meta parents?
  5. If a method is found is the search stopped even though another
    method with the same name might exist in a parallel chain?

I have made some written notes as I went along which might interest
you. It is useful to know how the reader is progressing.

def ClassA
def initialize
#some code
end
end

def ClassB
def ClassA.methodX
#code
end
def ClassB.methodY
#code
end
end

both work.
Is this a good idea to define a class method within a different
class? is this the point of OO or is it bad programming style?

Andy H. says

It depends. In general, that’s probably bad style as you’re likely
violating the encapsulation of ClassA.

Regards,

/\ndy

\newpage

class ClassA
def initialize
puts “something classA”
end
end

class ClassC
def initialize
puts “someting classC”
end
def methodY
puts “beach balls”
end
end

class ClassB < ClassC
def methodY
super
puts “something ClassB.methodY”
end
end

test = ClassA.new
stuart = ClassB.new
puts stuart.methodY

stuart = ClassB.methodY

or

stuart = ClassB.new
stuart.methodY

stuart is an object which is initialized of the class method as
ClassB.new which is mostly defined as an ordinary method called
initialize inside of and at the beginnning of the class as ClassB

Sometimes the object as stuart will be referred by as the receiver if
a method within the class by which the object as stuart is defined, is
called after the object name as stuart. i.e stuart.methodY. Stuart is
reffered by as the receiver so to indicate that the class of the
object as stuart, which in this case is the class as ClassB, contains
a method which the object as stuart may access ; i.e stuart.methodY.

The object as Stuart is related by the class as ClassB. The object as
stuart is of the class as ClassB. The word as related means the same
as the word as linked within this context.

Each class may be part of an inheritance chain.

But the class as classB may also be considered an object. Therefore
the class as classB itself may also be used as a receiver. e.g.

ClassB.methodZ

where the method as Z is defined within the class as ClassC : which is
the parentclass of ClassB.
or
where the method as Z is defined within the class as ClassB’ : which
is a virtual class of ClassB.
Because ClassB’ is the virtual class of ClassB and Class B is also the
subclass of ClassC, another virtual class as ClassC is established to
be the virtual parentclass of the virual class as ClassB’. None of
these virtual classes are supposed to be immediately visible. The
virtual class as ClassB’ will contain all the methods of ClassB and
this pattern is repeated through the parallel inheritance chain.

QUESTION
I’m trying to understand classes and objects. The Pick axe book
describes the method as “once” inside of the class as Date, and how this method is defined
by using the object singleton technique as “class << self”. Actually
the class as Date uses this method at several places. Until I saw the class as Date I thought that the
reason by this singleton techinique was to add and replace methods inside of classes at such circumstances when you
don’t have convenient ways to access by the class definition ; so I conclude that basically,
one should use this singleton technique when it’s not your class which you need to enhance. But the fact
that the class as Date uses this method several times indicates there is another reason to
use it.

which is derived from
comp.lang.ruby August 9 2005
Kelly F. wrote:

I’m trying to understand classes and objects. The Pick axe book
points out the “once” method in class Date and how it is defined
using the object singleton technique of “class << self”. Actually
Date uses this in several places. Up until seeing Date I thought the
reason for this idiom was to add/replace methods in classes when you
don’t have convenient access to the class definition
– basically,
use this when it’s not your class you need to enhance. But the fact
that Date uses it several times indicates there is another reason to
use it.

ANSWER

As you guessed, the reasons are different: typically you use “class
<<something…end” if you have to define several methods or if you
need a
class context for things to work (for example “alias”).

These are equivalent:

class Foo
class <<self
def m1() “foo” end
end

class <<Foo
def m2() “foo” end
end

def self.m3() “foo” end
def Foo.m4() “foo” end
end

class <<Foo
def m5() “foo” end
end

def Foo.m6() “foo” end

x = Foo
def x.m7() “foo” end

class <<x
def m8() “foo” end
end

Now you have methods m1 to m8 as instance methods of Foo. You can do
Foo.m1(), Foo.m2 etc.

More technically, with class <<something … end you make definition
for
the so called “singleton class” the class instance responsible for the
single instance at hand (which happens to be a class object in this
case;
but you can repeat the example above with any object instead of Foo).
You
cannot create instances from this class:

irb(main):001:0> class Foo
irb(main):002:1> p new
irb(main):003:1> end
#Foo:0x10192d58
=> nil
irb(main):004:0> class <<Foo
irb(main):005:1> p new
irb(main):006:1> end
TypeError: can’t create instance of virtual class
from (irb):5:in `new’
from (irb):5

– No virus found in this incoming message. Checked by AVG Free
Edition. Version: 7.5.467 / Virus Database: 269.7.7/816 - Release
Date: 23/05/2007 15:59

Thankyou for replying at such length. I am sure that what you have
explained I will understand properly soon. I think that this post
deserves some web links.

David R

On 5/24/07, [email protected]
[email protected] 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 T. 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 <<b #singleton class for the object referenced by b is created
now

end

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

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

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

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