A class that is a direct instance of standard-class
can
be redefined if the new class is also
a direct instance of standard-class
.
Redefining a class modifies the existing
class object to reflect the new class definition; it does not
create a new class object for the class.
Any method object created by a :reader, :writer,
or :accessor option specified by the old defclass
form is
removed from the corresponding generic function.
Methods specified by the new defclass
form are added.
When the class C is redefined, changes are propagated to its instances
and to instances of any of its subclasses. Updating such an
instance occurs at an implementation-dependent time, but no later than
the next time a slot
of that instance is read or written. Updating an
instance
does not change its identity as defined by the function eq
.
The updating process may change the slots of that
particular instance,
but it does not create a new instance. Whether
updating an instance consumes storage is implementation-dependent.
Note that redefining a class may cause slots to be added or deleted. If a class is redefined in a way that changes the set of local slots accessible in instances, the instances are updated. It is implementation-dependent whether instances are updated if a class is redefined in a way that does not change the set of local slots accessible in instances.
The value of a slot that is specified as shared both in the old class and in the new class is retained. If such a shared slot was unbound in the old class, it is unbound in the new class. Slots that were local in the old class and that are shared in the new class are initialized. Newly added shared slots are initialized.
Each newly added shared slot is set to the result of evaluating the
captured initialization form for the slot that was specified
in the defclass
form for the new class.
If there was no initialization form, the slot is unbound.
If a class is redefined in such a way that the set of
local slots accessible in an instance of the class
is changed, a two-step process of updating the instances of the
class takes place. The process may be explicitly started by
invoking the generic function make-instances-obsolete
. This
two-step process can happen in other circumstances in some implementations.
For example, in some implementations this two-step process is
triggered if the order of slots in storage is changed.
The first step modifies the structure of the instance by adding new local slots and discarding local slots that are not defined in the new version of the class. The second step initializes the newly-added local slots and performs any other user-defined actions. These two steps are further specified in the next two sections.
The first step modifies the structure of instances of the redefined
class to conform to its new class definition.
Local slots specified
by the new class definition that are not specified as either local or
shared by the old class are added, and slots
not specified as either
local or shared by the new class definition that are specified as
local by the old class are discarded.
The names of these added and discarded
slots are passed as arguments
to update-instance-for-redefined-class
as described in the next section.
The values of local slots specified by both the new and old classes are retained. If such a local slot was unbound, it remains unbound.
The value of a slot that is specified as shared in the old class and as local in the new class is retained. If such a shared slot was unbound, the local slot is unbound.
The second step initializes the newly added local slots and performs
any other user-defined actions. This step is implemented by the generic
function update-instance-for-redefined-class
, which is called after
completion of the first step of modifying the structure of the
instance.
The generic function update-instance-for-redefined-class
takes
four required arguments: the instance being updated after it has
undergone the first step, a list of the names of local slots that were
added, a list of the names of local slots that were discarded, and a
property list containing the slot names and values of
slots that were
discarded and had values. Included among the discarded slots are
slots that were local in the old class and that are shared in the new
class.
The generic function update-instance-for-redefined-class
also
takes any number of initialization arguments. When it is called by
the system to update an instance whose class
has been redefined, no
initialization arguments are provided.
There is a system-supplied primary method for
update-instance-for-redefined-class
whose parameter specializer
for its instance argument is the class standard-object
.
First this method checks the validity of initialization arguments and signals an
error if an initialization argument is supplied that is not declared
as valid. (For more information, see Section 7.1.2 (Declaring the Validity of Initialization Arguments).)
Then it calls the generic function
shared-initialize
with the following arguments: the
instance,
the list of names of
the newly added slots, and the initialization
arguments it received.
Methods for update-instance-for-redefined-class
may be
defined to specify actions to be taken when an instance is updated.
If only after methods for update-instance-for-redefined-class
are
defined, they will be run after the system-supplied primary method for
initialization and therefore will not interfere with the default
behavior of update-instance-for-redefined-class
. Because no
initialization arguments are passed to update-instance-for-redefined-class
when it is called by the system, the
initialization forms for slots
that are filled by before methods for update-instance-for-redefined-class
will not be evaluated by shared-initialize
.
Methods for shared-initialize
may be defined to customize
class redefinition. For more information, see Section 7.1.5 (Shared-Initialize).