Next: Performance, Previous: Two flavors of equality, Up: Behind the scenes
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; then type the text following the
st>
prompt.
st> Set superclass! HashedCollection st> HashedCollection superclass! Collection st> Collection superclass! Object st> Object superclass! nil
Nothing new for now. Let’s try something else:
st> #(1 2 3) class! Array st> '123' class! String st> Set class! Set class st> Set class class! Metaclass
You get it, that strange Set class
thing is something
called “a meta-class”... let’s go on:
st> ^Set class superclass! Collection class st> ^Collection class superclass! 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! 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! ClassDescription st> ^ClassDescription superclass! Behavior st> ^Behavior superclass! 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 := 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 0
If you send #class
repeatedly, it seems that you end up
in a loop made of class Metaclass
44 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.
Random class
implements creation and
initialization of its instances’ random number seed;
analogously, Metaclass class
implements creation and
initialization of its instances, which are metaclasses.
Metaclass
implements creation and initialization of
its instances, which are classes (subclasses of Class
).
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.
Next: Performance, Previous: Two flavors of equality, Up: Behind the scenes