When a class is defined using define-class
and the class name was
previously defined, by default the new binding just replaces the old
binding. This is the normal behavior for define
. However if
both the old and new bindings are redefinable classes (instances of
<redefinable-class>
), then the class will be updated in place,
and its instances lazily migrated over.
The way that the class is updated and the way that the instances migrate over are of course part of the meta-object protocol. However the default behavior usually suffices, and it goes as follows.
<my-class>
are converted to be
instances of the new class. This is achieved by preserving the values
of slots that exist in both the old and new definitions, and
initializing the values of new slots in the usual way (see make).
<my-class>
are redefined, as though
the define-class
expressions that defined them were re-evaluated
following the redefinition of <my-class>
, and the class
redefinition process described here is applied recursively to the
redefined subclasses.
<my-class>
is no
longer needed and so can be allowed to be garbage collected.
To keep things tidy, GOOPS also needs to do a little housekeeping on methods that are associated with the redefined class.
<my-class>
metaobject
as one of its formal parameter specializers must be updated to refer to
the new <my-class>
metaobject. (Whenever a new generic function
method is defined, define-method
adds the method to a list stored
in the class metaobject for each class used as a formal parameter
specializer, so it is easy to identify all the methods that must be
updated when a class is redefined.)
If this class redefinition strategy strikes you as rather counter-intuitive, bear in mind that it is derived from similar behavior in other object systems such as CLOS, and that experience in those systems has shown it to be very useful in practice.
Also bear in mind that, like most of GOOPS’ default behavior, it can be customized…