A metaclass is the class of an object which represents a GOOPS class. Put more succinctly, a metaclass is a class’s class.
Most GOOPS classes have the metaclass <class>
and, by default,
any new class that is created using define-class
has the
metaclass <class>
.
But what does this really mean? To find out, let’s look in more detail
at what happens when a new class is created using define-class
:
(define-class <my-class> (<object>) . slots)
Guile expands this to something like:
(define <my-class> (class (<object>) . slots))
which in turn expands to:
(define <my-class> (make <class> #:dsupers (list <object>) #:slots slots))
As this expansion makes clear, the resulting value of <my-class>
is an instance of the class <class>
with slot values specifying
the superclasses and slot definitions for the class <my-class>
.
(#:dsupers
and #:slots
are initialization keywords for the
dsupers
and dslots
slots of the <class>
class.)
Now suppose that you want to define a new class with a metaclass other
than the default <class>
. This is done by writing:
(define-class <my-class2> (<object>) slot ... #:metaclass <my-metaclass>)
and Guile expands this to something like:
(define <my-class2> (make <my-metaclass> #:dsupers (list <object>) #:slots slots))
In this case, the value of <my-class2>
is an instance of the more
specialized class <my-metaclass>
. Note that
<my-metaclass>
itself must previously have been defined as a
subclass of <class>
. For a full discussion of when and how it is
useful to define new metaclasses, see MOP Specification.
Now let’s make an instance of <my-class2>
:
(define my-object (make <my-class2> ...))
All of the following statements are correct expressions of the
relationships between my-object
, <my-class2>
,
<my-metaclass>
and <class>
.
my-object
is an instance of the class <my-class2>
.
<my-class2>
is an instance of the class <my-metaclass>
.
<my-metaclass>
is an instance of the class <class>
.
my-object
is <my-class2>
.
<my-class2>
is <my-metaclass>
.
<my-metaclass>
is <class>
.