www.delorie.com/gnu/docs/smalltalk/gst_94.html   search  
 
Buy GNU books!


GNU Smalltalk User's Guide

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.11.3 The truth about metaclasses

Everybody, sooner or later, looks for the implementation of the #new method in Object class. To their surprise, they don't find it; if they're really smart, they search for implementors of #new in the image and they find out it is implemented by Behavior... which turns out to be a subclass of Object! The truth starts showing to their eyes about that sentence that everybody says but few people understand: "classes are objects".

Huh? Classes are objects?!? Let me explain.

Open up an image; type `gst -r' so that you have no run-time statistics on the screen; then type the text following the st> prompt. Open up an image; type `gst -r' so that you have no run-time statistics on the screen; then type the text printed in mono-spaced font.

 
    st> ^Set superclass!
    returned value is HashedCollection

    st> ^HashedCollection superclass!
    returned value is Collection

    st> ^Collection superclass!
    returned value is Object

    st> ^Object superclass!
    returned value is nil

Nothing new for now. Let's try something else:

 
    st> ^#(1 2 3) class!
    returned value is Array

    st> ^'123' class!
    returned value is String

    st> ^Set class!
    returned value is Set class

    st> ^Set class class!
    returned value is Metaclass

You get it, that strange Set class thing is something called "a meta-class"... let's go on:

 
    st> ^Set class superclass!
    returned value is Collection class

    st> ^Collection class superclass!
    returned value is Object class 

You see, there is a sort of `parallel' hierarchy between classes and metaclasses. When you create a class, Smalltalk creates a metaclass; and just like a class describes how methods for its instances work, a metaclass describes how class methods for that same class work.

Set is an instance of the metaclass, so when you invoke the #new class method, you can also say you are invoking an instance method implemented by Set class. Simply put, class methods are a lie: they're simply instance methods that are understood by instances of metaclasses.

Now you would expect that Object class superclass answers nil class, that is UndefinedObject. Yet you saw that #new is not implemented there... let's try it:

 
    st> ^Object class superclass!
    returned value is Class

Uh?!? Try to read it aloud: the Object class class inherits from the Class class. Class is the abstract superclass of all metaclasses, and provides the logic that allows you to create classes in the image. But it is not the termination point:

 
    st> ^Class superclass!
    returned value is ClassDescription

    st> ^ClassDescription superclass!
    returned value is Behavior

    st> ^Behavior superclass!
    returned value is Object

Class is a subclass of other classes. ClassDescription is abstract; Behavior is concrete but lacks the methods and state that allow classes to have named instance variables, class comments and more. Its instances are called light-weight classes because they don't have separate metaclasses, instead they all share Behavior itself as their metaclass.

Evaluating Behavior superclass we have worked our way up to class Object again: Object is the superclass of all instances as well as all metaclasses. This complicated system is extremely powerful, and allows you to do very interesting things that you probably did without thinking about it--for example, using methods such as #error: or #shouldNotImplement in class methods.

Now, one final question and one final step: what are metaclasses instances of? The question makes sense: if everything has a class, should not metaclasses have one?

Evaluate the following:

 
    st> | meta |
    st> meta := Set class
    st> 0 to: 4 do: [ :i |
    st>     i timesRepeat: [ Transcript space ].
    st>     meta printNl.
    st>     meta := meta class.
    st> ]!
    Set class
     Metaclass
      Metaclass class
       Metaclass
        Metaclass class
    returned value is nil

If you send #class repeatedly, it seems that you end up in a loop made of class Metaclass(41) and its own metaclass, Metaclass class. It looks like class Metaclass is an instance of an instance of itself.

To understand the role of Metaclass, it can be useful to know that the class creation is implemented there. Think about it.

The circle is closed. In the end, this mechanism implements a clean, elegant and (with some contemplation) understandable facility for self-definition of classes. In other words, it is what allows classes to talk about themselves, posing the foundation for the creation of browsers.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster     delorie software   privacy  
  Copyright 2003   by The Free Software Foundation     Updated Jun 2003