DEFCLASSCLASS-NAMECLOS:CLASS-DIRECT-SUPERCLASSESCLOS:CLASS-DIRECT-SLOTSCLOS:CLASS-DIRECT-DEFAULT-INITARGSCLOS:CLASS-PRECEDENCE-LISTCLOS:CLASS-DIRECT-SUBCLASSESCLOS:CLASS-SLOTSCLOS:CLASS-DEFAULT-INITARGSCLOS:CLASS-FINALIZED-PCLOS:CLASS-PROTOTYPE(SETF CLASS-NAME)CLOS:ENSURE-CLASSCLOS:ENSURE-CLASS-USING-CLASSCLOS:FINALIZE-INHERITANCEMAKE-INSTANCEALLOCATE-INSTANCECLOS:VALIDATE-SUPERCLASSCLOS:COMPUTE-DIRECT-SLOT-DEFINITION-INITARGSCLOS:DIRECT-SLOT-DEFINITION-CLASSCLOS:COMPUTE-CLASS-PRECEDENCE-LISTCLOS:COMPUTE-SLOTSCLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITIONCLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGSCLOS:EFFECTIVE-SLOT-DEFINITION-CLASSCLOS:COMPUTE-DEFAULT-INITARGSDEFCLASSThe evaluation or execution of a DEFCLASS form results in a call
to the CLOS:ENSURE-CLASS function. The arguments received by CLOS:ENSURE-CLASS
are derived from the DEFCLASS form in a defined way. The exact
macro-expansion of the DEFCLASS form is not defined, only the
relationship between the arguments to the DEFCLASS macro and the
arguments received by the CLOS:ENSURE-CLASS function. Examples of typical
DEFCLASS forms and sample expansions are shown in the following two
examples:
A DEFCLASS form with
standard slot and class options and an expansion of it that would
result in the proper call to CLOS:ENSURE-CLASS.
(defclass plane (moving-object graphics-object)
((altitude :initform 0 :accessor plane-altitude)
(speed))
(:default-initargs :engine *jet*))
(ensure-class 'plane
':direct-superclasses '(moving-object graphics-object)
':direct-slots (list (list ':name 'altitude
':initform '0
':initfunction #'(lambda () 0)
':readers '(plane-altitude)
':writers '((setf plane-altitude)))
(list ':name 'speed))
':direct-default-initargs (list (list ':engine
'*jet*
#'(lambda () *jet*))))
A DEFCLASS form
with non-standard class and slot options, and an expansion of it which
results in the proper call to CLOS:ENSURE-CLASS. Note that the order of
the slot options has not affected the order of the properties in the
canonicalized slot specification, but has affected the order of the elements
in the lists which are the values of those properties.
(defclass sst (plane)
((mach mag-step 2
locator sst-mach
locator mach-location
:reader mach-speed
:reader mach))
(:metaclass faster-class)
(another-option foo bar))
(ensure-class 'sst
':direct-superclasses '(plane)
':direct-slots (list (list ':name 'mach
':readers '(mach-speed mach)
'mag-step '2
'locator '(sst-mach mach-location)))
':metaclass 'faster-class
'another-option '(foo bar))
name argument to DEFCLASS
becomes the value of the first argument to CLOS:ENSURE-CLASS. This is
the only positional argument accepted by CLOS:ENSURE-CLASS; all other
arguments are keyword arguments.:DIRECT-SUPERCLASSES argument to DEFCLASS
becomes the value of the :DIRECT-SUPERCLASSES keyword argument to
CLOS:ENSURE-CLASS.The :DIRECT-SLOTS argument to DEFCLASS becomes
the value of the :DIRECT-SLOTS keyword argument to CLOS:ENSURE-CLASS.
Special processing of this value is done to regularize the form of
each slot specification and to properly capture the lexical scope of
the initialization forms. This is done by converting each slot
specification to a property list called a
canonicalized slot specification.
The resulting list of canonicalized slot specifications is the value
of the :DIRECT-SLOTS keyword argument.
Canonicalized slot
specifications are later used as the keyword arguments to a generic
function which will, in turn, pass them to MAKE-INSTANCE for use as
a set of initialization arguments. Each canonicalized slot specification is
formed from the corresponding slot specification as follows:
:NAME
property. This property appears in every
canonicalized slot specification.:INITFORM slot option is present in
the slot specification, then both the :INITFORM and
:INITFUNCTION properties are present in the canonicalized slot specification.
The value of the :INITFORM property is the
initialization form. The value of the :INITFUNCTION property is
a function of zero arguments which, when called, returns the result
of evaluating the initialization form in its proper lexical environment.
:INITFORM slot option is not present in
the slot specification, then either the :INITFUNCTION property
will not appear, or its value will be false. In such cases, the
value of the :INITFORM property, or whether it appears, is
unspecified.:INITARGS property is a list
of the values of each :INITARG slot option. If there are no
:INITARG slot options, then either the :INITARGS property
will not appear or its value will be the empty list.
:READERS property is a list of
the values of each :READER and :ACCESSOR slot option. If
there are no :READER or :ACCESSOR slot options, then either
the :READERS property will not appear or its value will be the
empty list.:WRITERS property is a list of
the values specified by each :WRITER and :ACCESSOR slot
option. The value specified by a :WRITER slot option is just
the value of the slot option. The value specified by an
:ACCESSOR slot option is a two element list: the first element
is the symbol SETF, the second element is the value of the slot
option. If there are no :WRITER or :ACCESSOR slot options,
then either the :WRITERS property will not appear or its value
will be the empty list.:DOCUMENTATION property is the
value of the :DOCUMENTATION slot option. If there is no
:DOCUMENTATION slot option, then either the :DOCUMENTATION
property will not appear or its value will be false.
:ALLOCATION and :TYPE), but also any other options and
values appearing in the slot specification. If one of these slot
options appears more than once, the value of the property will be a
list of the specified values.The default initargs class
option, if it is present in the DEFCLASS form, becomes the value of
the :DIRECT-DEFAULT-INITARGS keyword argument to CLOS:ENSURE-CLASS.
Special processing of this value is done to properly capture the
lexical scope of the default value forms. This is done by converting
each default initarg in the class option into a
canonicalized default initialization argument.
The resulting list of canonicalized default initialization arguments is the value of
the :DIRECT-DEFAULT-INITARGS keyword argument to CLOS:ENSURE-CLASS.
A canonicalized default initarg is a list of three elements. The first element is the name; the second is the actual form itself; and the third is a function of zero arguments which, when called, returns the result of evaluating the default value form in its proper lexical environment.
If a default initargs
class option is not present in the DEFCLASS form,
:DIRECT-DEFAULT-INITARGS NIL is passed to CLOS:ENSURE-CLASS.
This is needed to
fulfill the [ANSI CL standard] requirement (see Section 4.6, “Redefining Classes ”) that
the resulting CLASS object reflects the DEFCLASS form.
The metaclass class
option, if it is present in the DEFCLASS form, becomes the value of
the :METACLASS keyword argument to CLOS:ENSURE-CLASS.
If a metaclass
class option is not present in the DEFCLASS form,
:METACLASS STANDARD-CLASS is passed to CLOS:ENSURE-CLASS.
This is needed to
fulfill the [ANSI CL standard] requirement (see Section 4.6, “Redefining Classes ”) that
the resulting CLASS object reflects the DEFCLASS form.
The documentation class
option, if it is present in the DEFCLASS form, becomes the value of
the :DOCUMENTATION keyword argument to CLOS:ENSURE-CLASS.
If a documentation
class option is not present in the DEFCLASS form,
:DIRECT-DEFAULT-INITARGS NIL is passed to CLOS:ENSURE-CLASS.
This is needed to
fulfill the [ANSI CL standard] requirement (see Section 4.6, “Redefining Classes ”) that
the resulting CLASS object reflects the DEFCLASS form.
Any other class options become the value of keyword
arguments with the same name. The value of the keyword argument is
the tail of the class option. An ERROR is SIGNALed if any class
option appears more than once in the DEFCLASS form.
The default initargs of the
metaclass are added at the end of the list
of arguments to pass to CLOS:ENSURE-CLASS.
This is needed to
fulfill the [ANSI CL standard] requirement (see Section 4.6, “Redefining Classes ”) that
the resulting CLASS object reflects the DEFCLASS form.
In the call to CLOS:ENSURE-CLASS, every element of its arguments
appears in the same left-to-right order as the corresponding element of
the DEFCLASS form, except that the order of the properties of
canonicalized slot specifications is unspecified. The values of
properties in canonicalized slot specifications do follow this ordering
requirement. Other ordering relationships in the keyword arguments to
CLOS:ENSURE-CLASS are unspecified.
The result of the call to CLOS:ENSURE-CLASS is returned as the result
of evaluating or executing the DEFCLASS form.
CLASS-NAMECLOS:CLASS-DIRECT-SUPERCLASSESCLOS:CLASS-DIRECT-SLOTSCLOS:CLASS-DIRECT-DEFAULT-INITARGSCLOS:CLASS-PRECEDENCE-LISTCLOS:CLASS-DIRECT-SUBCLASSESCLOS:CLASS-SLOTSCLOS:CLASS-DEFAULT-INITARGSCLOS:CLASS-FINALIZED-PCLOS:CLASS-PROTOTYPEIn this and the following sections, the “reader” generic functions which simply return information associated with a particular kind of metaobject are presented together. General information is presented first, followed by a description of the purpose of each, and ending with the specified methods for these generic functions.
The reader generic functions which simply return information associated with class metaobjects are presented together in this section.
Each of the reader generic functions for class metaobjects has the same
syntax, accepting one required argument called class, which must be
a class metaobject; otherwise, an ERROR is SIGNALed. An ERROR is also SIGNALed if
the class metaobject has not been initialized.
These generic functions can be called by the user or the implementation.
For any of these generic functions which returns a list, such lists will not be mutated by the implementation. The results are undefined if a portable program allows such a list to be mutated.
CLASS-NAME(CLASS-NAME class)Returns the name of class. This value can be any Lisp object,
but is usually a symbol, or NIL if the class has no name. This is the
defaulted value of the :NAME initialization argument that was
associated with the class during initialization or reinitialization.
(Also see (SETF CLASS-NAME).)
CLOS:CLASS-DIRECT-SUPERCLASSES(CLOS:CLASS-DIRECT-SUPERCLASSES class)Returns a list of the direct superclasses of class. The
elements of this list are class metaobjects. The empty list is returned if
class has no direct superclasses. This is the defaulted value of
the :DIRECT-SUPERCLASSES initialization argument that was associated
with the class during initialization or reinitialization.
For a class that has not yet been finalized,
the returned list may contain CLOS:FORWARD-REFERENCED-CLASS instances as
placeholder for classes that were not yet defined when finalization of
the class was last attempted.
CLOS:CLASS-DIRECT-SLOTS(CLOS:CLASS-DIRECT-SLOTS class)Returns a set of the direct slots of class. The elements of
this set are direct slot definition metaobjects. If the class has no direct slots, the empty set
is returned. This is the defaulted value of the :DIRECT-SLOTS
initialization argument that was associated with the class during
initialization and reinitialization.
CLOS:CLASS-DIRECT-DEFAULT-INITARGSReturns a list of the direct default initialization arguments for
class. Each element of this list is a canonicalized default initialization argument.
The empty list is returned if class has no
direct default initialization arguments. This is the defaulted value of
the :DIRECT-DEFAULT-INITARGS initialization argument that was
associated with the class during initialization or reinitialization.
CLOS:CLASS-PRECEDENCE-LIST(CLOS:CLASS-PRECEDENCE-LIST class)Returns the class precedence list of class.
The elements of this list are class metaobjects.
During class finalization CLOS:FINALIZE-INHERITANCE calls
CLOS:COMPUTE-CLASS-PRECEDENCE-LIST to compute the class precedence list of the class. That
value is associated with the class metaobject and is returned by CLOS:CLASS-PRECEDENCE-LIST.
This generic function SIGNALs an ERROR if class has not been finalized.
CLOS:CLASS-DIRECT-SUBCLASSES(CLOS:CLASS-DIRECT-SUBCLASSES class)Returns a set of the direct subclasses of class. The elements
of this set are class metaobjects that all mention this class among their direct
superclasses. The empty set is returned if class has no direct
subclasses. This value is maintained by the generic functions
CLOS:ADD-DIRECT-SUBCLASS and CLOS:REMOVE-DIRECT-SUBCLASS.
The set of direct subclasses of a class is
internally managed as a EXT:WEAK-LIST. Therefore the existence of
the CLOS:CLASS-DIRECT-SUBCLASSES function does not prevent otherwise
unreferenced classes from being garbage-collected.
CLOS:CLASS-SLOTS(CLOS:CLASS-SLOTS class)Returns a possibly empty set of the slots accessible in instances
of class. The elements of this set are effective slot definition metaobjects.
During class finalization CLOS:FINALIZE-INHERITANCE calls
CLOS:COMPUTE-SLOTS to compute the slots of the class. That value is
associated with the class metaobject and is returned by CLOS:CLASS-SLOTS.
This generic function SIGNALs an ERROR if class has not been finalized.
CLOS:CLASS-DEFAULT-INITARGS(CLOS:CLASS-DEFAULT-INITARGS class)Returns a list of the default initialization arguments for class.
Each element of this list is a canonicalized default initialization argument.
The empty list is returned if class has no
default initialization arguments.
During finalization CLOS:FINALIZE-INHERITANCE calls
CLOS:COMPUTE-DEFAULT-INITARGS to compute the default initialization
arguments for the class. That value is associated with the class metaobject and
is returned by CLOS:CLASS-DEFAULT-INITARGS.
This generic function SIGNALs an ERROR if class has not been
finalized.
CLOS:CLASS-FINALIZED-P(CLOS:CLASS-FINALIZED-P class)Returns true if class has been finalized. Returns false
otherwise. Also returns false if the class has not been initialized.
CLOS:CLASS-PROTOTYPE(CLOS:CLASS-PROTOTYPE class)Returns a prototype instance of class. Whether the instance
is initialized is not specified. The results are undefined if a
portable program modifies the binding of any slot of a prototype instance.
This generic function SIGNALs an ERROR if class has not been finalized.
This allows non-consing[3]
access to slots with allocation :CLASS:
(defclass counter () ((count :allocation :class :initform 0 :reader how-many))) (defmethod initialize-instance :after ((obj counter) &rest args) (incf (slot-value obj 'count))) (defclass counted-object (counter) ((name :initarg :name)))
Now one can find out how many COUNTED-OBJECTs
have been created by using
(HOW-MANY (:
CLOS:CLASS-PROTOTYPE (FIND-CLASS 'COUNTER)))
(MAKE-INSTANCE'counted-object :name 'foo) ⇒#<COUNTED-OBJECT #x203028C9>(HOW-MANY (CLOS:CLASS-PROTOTYPE(FIND-CLASS'counter))) ⇒1(MAKE-INSTANCE'counted-object :name 'bar) ⇒#<COUNTED-OBJECT #x20306CB1>(HOW-MANY (CLOS:CLASS-PROTOTYPE(FIND-CLASS'counter))) ⇒2
The specified methods for the class metaobject reader generic functions are presented below.
Each entry in the table indicates a method on one of the reader generic functions, specialized to a specified class. The number in each entry is a reference to the full description of the method. The full descriptions appear after the table.
Class Reader Methods
CLOS:FINALIZE-INHERITANCE
(STANDARD-CLASS) or
CLOS:FINALIZE-INHERITANCE
(CLOS:FUNCALLABLE-STANDARD-CLASS)SIGNALs an ERROR.CLOS:ADD-DIRECT-SUBCLASS(CLASS
CLASS) and CLOS:REMOVE-DIRECT-SUBCLASS
(CLASS CLASS).
This method can be overridden only if those methods are overridden as
well.Class finalization is the process of computing the information a class inherits from its superclasses and preparing to actually allocate instances of the class. The class finalization process includes computing the class's class precedence list, the full set of slots accessible in instances of the class and the full set of default initialization arguments for the class. These values are associated with the class metaobject and can be accessed by calling the appropriate reader. In addition, the class finalization process makes decisions about how instances of the class will be implemented.
To support forward-referenced superclasses, and to account for the
fact that not all classes are actually instantiated, class finalization
is not done as part of the initialization of the class metaobject. Instead,
finalization is done as a separate protocol, invoked by calling the
generic function CLOS:FINALIZE-INHERITANCE. The exact point at which
CLOS:FINALIZE-INHERITANCE is called depends on the class of the class metaobject; for
STANDARD-CLASS it is called sometime after all the classes
superclasses are defined, but no later than when the first instance of
the class is allocated (by ALLOCATE-INSTANCE).
The first step of class finalization is computing the class
precedence list. Doing this first allows subsequent steps to access the
class precedence list. This step is performed by calling the generic
function CLOS:COMPUTE-CLASS-PRECEDENCE-LIST. The value returned from this call is associated
with the class metaobject and can be accessed by calling the CLOS:CLASS-PRECEDENCE-LIST generic
function.
The second step is computing the full set of slots that will be
accessible in instances of the class. This step is performed by calling
the generic function CLOS:COMPUTE-SLOTS. The result of this call is a list
of effective slot definition metaobjects. This value is associated with the class metaobject and can
be accessed by calling the CLOS:CLASS-SLOTS generic function.
The behavior of CLOS:COMPUTE-SLOTS is itself layered, consisting of
calls to CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS and CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION.
The final step of class finalization is computing the full set of
initialization arguments for the class. This is done by calling the
generic function CLOS:COMPUTE-DEFAULT-INITARGS. The value returned by this
generic function is associated with the class metaobject and can be
accessed by calling CLOS:CLASS-DEFAULT-INITARGS.
If the class was previously finalized, CLOS:FINALIZE-INHERITANCE may
call MAKE-INSTANCES-OBSOLETE. The circumstances under which this
happens are described in the [ANSI CL standard] section
Section 4.6, “Redefining Classes ”.
Forward-referenced classes, which provide a temporary definition
for a class which has been referenced but not yet defined, can never be
finalized. An ERROR is SIGNALed if CLOS:FINALIZE-INHERITANCE is called on a
forward-referenced class.
A class metaobject can be created by calling MAKE-INSTANCE.
The initialization arguments establish the definition of the class.
A class metaobject can be redefined by calling REINITIALIZE-INSTANCE.
Some classes of class metaobject do not support redefinition;
in these cases, REINITIALIZE-INSTANCE SIGNALs an ERROR.
Initialization of a class metaobject must be done by calling MAKE-INSTANCE
and allowing it to call INITIALIZE-INSTANCE. Reinitialization of a
class metaobject must be done by calling REINITIALIZE-INSTANCE.
Portable programs must not
INITIALIZE-INSTANCE directly to
initialize a class metaobject;SHARED-INITIALIZE directly to
initialize or reinitialize a class metaobject;CHANGE-CLASS to change the class of any
class metaobject or to turn a non-class object into a
class metaobject.Since metaobject classes may not be redefined,
no behavior is specified for the result of calls to
UPDATE-INSTANCE-FOR-REDEFINED-CLASS on class metaobjects.
Since the class of class metaobjects may not be changed,
no behavior is specified for the result of calls to
UPDATE-INSTANCE-FOR-DIFFERENT-CLASS on class metaobjects.
During initialization or reinitialization, each initialization argument is checked for errors and then associated with the class metaobject. The value can then be accessed by calling the appropriate accessor as shown in Table 29.2, “Initialization arguments and accessors for class metaobjects”.
This section begins with a description of the error checking and processing of each initialization argument. This is followed by a table showing the generic functions that can be used to access the stored initialization arguments. Initialization behavior specific to the different specified class metaobject classes comes next. The section ends with a set of restrictions on portable methods affecting class metaobject initialization and reinitialization.
In these descriptions, the phrase “this argument defaults to
value” means that when that initialization argument is not
supplied, initialization or reinitialization is performed as if
value had been supplied. For some initialization arguments this
could be done by the use of default initialization arguments, but
whether it is done this way is not specified. Implementations are free
to define default initialization arguments for specified class metaobject classes.
Portable programs are free to define default initialization arguments
for portable subclasses of the class CLASS.
Unless there is a specific note to the contrary, then during reinitialization, if an initialization argument is not supplied, the previously stored value is left unchanged.
The :DIRECT-DEFAULT-INITARGS argument is a list
of canonicalized default initialization arguments.
An ERROR is SIGNALed if this value is not a proper list, or if any
element of the list is not a canonicalized default initialization argument.
If the class metaobject is being initialized, this argument defaults to the empty list.
The :DIRECT-SLOTS argument is a list of
canonicalized slot specifications.
An ERROR is SIGNALed if this value is not a proper list or if any
element of the list is not a canonicalized slot specification.
After error checking, this value is converted to a
list of direct slot definition metaobjects before it is associated with the class metaobject. Conversion
of each canonicalized slot specification to a direct slot definition metaobject is a two-step process.
First, the generic function CLOS:DIRECT-SLOT-DEFINITION-CLASS is called with the class metaobject and
the canonicalized slot specification to determine the class of the new
direct slot definition metaobject; this permits both the class metaobject and the
canonicalized slot specification to control the resulting direct slot definition metaobject class.
Second, MAKE-INSTANCE is applied to the direct slot definition metaobject class and the
canonicalized slot specification.
This conversion could be implemented as shown in the
following code:
(DEFUNconvert-to-direct-slot-definition (class canonicalized-slot) (APPLY#'MAKE-INSTANCE(APPLY#'CLOS:DIRECT-SLOT-DEFINITION-CLASSclass canonicalized-slot) canonicalized-slot))
If the class metaobject is being initialized, this argument defaults to the empty list.
Once the direct slot definition metaobjects have been created, the specified reader and
writer methods are created. The generic functions
CLOS:READER-METHOD-CLASS and CLOS:WRITER-METHOD-CLASS are called to
determine the classes of the method metaobjects created.
The :DIRECT-SUPERCLASSES argument is a list of
class metaobjects. Classes which do not support multiple inheritance
signal an error if the list contains more than one element.
An ERROR is SIGNALed if this value is not a proper list or if
CLOS:VALIDATE-SUPERCLASS applied to class and any element of this
list returns false.
When the class metaobject is being initialized, and this argument is
either not supplied or is the empty list, this argument defaults as
follows: if the class is an instance of STANDARD-CLASS or one of
its subclasses the default value is a list of the class
STANDARD-OBJECT; if the class is an instance of
CLOS:FUNCALLABLE-STANDARD-CLASS or one of its subclasses the default
value is a list of the class
CLOS:FUNCALLABLE-STANDARD-OBJECT.
If the class is an instance of
STRUCTURE-CLASS or one of its subclasses the default value is a
list of the class STRUCTURE-OBJECT
After any defaulting of the value, the generic function
CLOS:ADD-DIRECT-SUBCLASS is called once for each element of the list.
When the class metaobject is being reinitialized and this
argument is supplied, the generic function CLOS:REMOVE-DIRECT-SUBCLASS
is called once for each class metaobject in the previously stored value but not
in the new value; the generic function CLOS:ADD-DIRECT-SUBCLASS is
called once for each class metaobject in the new value but not in the
previously stored value.
:DOCUMENTATION argument is
a STRING or NIL. An ERROR is SIGNALed if it is not. This argument default
to NIL during initialization.The :NAME argument is an object.
If the class is being initialized, this argument defaults to
NIL.
After the processing and defaulting of initialization arguments described above, the value of each initialization argument is associated with the class metaobject. These values can then be accessed by calling the corresponding generic function. The correspondences are as follows:
Table 29.2. Initialization arguments and accessors for class metaobjects
| Initialization Argument | Generic Function |
|---|---|
:DIRECT-DEFAULT-INITARGS | CLOS:CLASS-DIRECT-DEFAULT-INITARGS |
:DIRECT-SLOTS | CLOS:CLASS-DIRECT-SLOTS |
:DIRECT-SUPERCLASSES | CLOS:CLASS-DIRECT-SUPERCLASSES |
:DOCUMENTATION | DOCUMENTATION |
:NAME | CLASS-NAME |
Instances of the class STANDARD-CLASS support multiple
inheritance and reinitialization. Instances of the class
CLOS:FUNCALLABLE-STANDARD-CLASS support multiple inheritance and
reinitialization. For forward referenced classes, all of the
initialization arguments default to NIL.
Instances of the class STRUCTURE-CLASS do
not support multiple inheritance and reinitialization.
Since built-in classes cannot be created or reinitialized by the
user, an ERROR is SIGNALed if INITIALIZE-INSTANCE or REINITIALIZE-INSTANCE
are called to initialize or reinitialize a derived instance of the class
BUILT-IN-CLASS.
It is not specified which methods provide the initialization and reinitialization behavior described above. Instead, the information needed to allow portable programs to specialize this behavior is presented as a set of restrictions on the methods a portable program can define. The model is that portable initialization methods have access to the class metaobject when either all or none of the specified initialization has taken effect.
These restrictions govern the methods that a portable program can
define on the generic functions INITIALIZE-INSTANCE,
REINITIALIZE-INSTANCE, and SHARED-INITIALIZE.
These restrictions apply only to methods on these generic functions for
which the first specializer is a subclass of the class CLASS.
Other portable methods on these generic functions are not affected by
these restrictions.
SHARED-INITIALIZE.For INITIALIZE-INSTANCE and REINITIALIZE-INSTANCE:
The results are undefined if any of these restrictions are violated.
class metaobjects created with MAKE-INSTANCE are usually anonymous
; that is, they have no proper name.
An anonymous class metaobject can be given a proper name using
( and
SETF FIND-CLASS)(.SETF CLASS-NAME)
When a class metaobject is created with MAKE-INSTANCE, it is initialized
in the usual way. The initialization arguments passed to
MAKE-INSTANCE are use to establish the definition of the class. Each
initialization argument is checked for errors and associated with the
class metaobject. The initialization arguments correspond roughly to the
arguments accepted by the DEFCLASS macro, and more closely to the
arguments accepted by the CLOS:ENSURE-CLASS function.
Some class metaobject classes allow their instances to be
redefined. When permissible, this is done by calling
REINITIALIZE-INSTANCE. This is discussed in the
next section.
An example of creating an anonymous class directly using
MAKE-INSTANCE follows:
(flet ((zero () 0)
(propellor () *propellor*))
(make-instance 'standard-class
:name '(my-class foo)
:direct-superclasses (list (find-class 'plane)
another-anonymous-class)
:direct-slots `((:name x
:initform 0
:initfunction ,#'zero
:initargs (:x)
:readers (position-x)
:writers ((setf position-x)))
(:name y
:initform 0
:initfunction ,#'zero
:initargs (:y)
:readers (position-y)
:writers ((setf position-y))))
:direct-default-initargs `((:engine *propellor* ,#'propellor))))
Some class metaobject classes allow their instances to be reinitialized.
This is done by calling REINITIALIZE-INSTANCE. The initialization
arguments have the same interpretation as in class initialization.
If the class metaobject was finalized before the call to REINITIALIZE-INSTANCE,
CLOS:FINALIZE-INHERITANCE will be called again once all the initialization
arguments have been processed and associated with the class metaobject.
In addition, once finalization is complete, any dependents of the
class metaobject will be updated by calling CLOS:UPDATE-DEPENDENT.
(SETF CLASS-NAME)CLOS:ENSURE-CLASSCLOS:ENSURE-CLASS-USING-CLASSCLOS:FINALIZE-INHERITANCEMAKE-INSTANCEALLOCATE-INSTANCECLOS:VALIDATE-SUPERCLASSCLOS:COMPUTE-DIRECT-SLOT-DEFINITION-INITARGSCLOS:DIRECT-SLOT-DEFINITION-CLASSCLOS:COMPUTE-CLASS-PRECEDENCE-LISTCLOS:COMPUTE-SLOTSCLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITIONCLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGSCLOS:EFFECTIVE-SLOT-DEFINITION-CLASSCLOS:COMPUTE-DEFAULT-INITARGS(SETF CLASS-NAME)((SETF CLASS-NAME) new-name
class)classnew-namenew-name argument.This function changes the name of class to new-name.
This value is usually a symbol, or NIL if the class has no name.
This function works by calling REINITIALIZE-INSTANCE with
class as its first argument, the symbol :NAME as its second
argument and new-name as its third argument.
CLOS:ENSURE-CLASS(CLOS:ENSURE-CLASS name &KEY
&ALLOW-OTHER-KEYS)nameSYMBOL.CLOS:ENSURE-CLASS-USING-CLASS,
others are processed during initialization of the class metaobject
(as described in Section 29.3.5.1, “Initialization of class metaobjects”).
This function is called to define or redefine a
class with the specified name, and can be called by the user or the
implementation. It is the functional equivalent of DEFCLASS, and
is called by the expansion of the DEFCLASS macro.
The behavior of this function is actually implemented by the
generic function CLOS:ENSURE-CLASS-USING-CLASS. When CLOS:ENSURE-CLASS is called,
it immediately calls CLOS:ENSURE-CLASS-USING-CLASS and returns that result as its
own.
The first argument to CLOS:ENSURE-CLASS-USING-CLASS is computed as
follows:
name names a class (FIND-CLASS returns a
class when called with name) use that class.NIL.
The second argument is name. The remaining arguments are the
complete set of keyword arguments received by the CLOS:ENSURE-CLASS
function.
CLOS:ENSURE-CLASS-USING-CLASS(CLOS:ENSURE-CLASS-USING-CLASS class name &KEY
:DIRECT-DEFAULT-INITARGS :DIRECT-SLOTS :DIRECT-SUPERCLASSES
:NAME :METACLASS &ALLOW-OTHER-KEYS)
classNIL.name:METACLASSSTANDARD-CLASS. If a class name is supplied, it is interpreted
as the class with that name. If a class name is supplied, but
there is no such class, an ERROR is SIGNALed.:DIRECT-SUPERCLASSESERROR is SIGNALed if this argument is not a
proper list.This generic function is called to define or modify
the definition of a named class. It is called by the CLOS:ENSURE-CLASS
function. It can also be called directly.
The first step performed by this generic function is to compute the set of initialization arguments which will be used to create or reinitialize the named class. The initialization arguments are computed from the full set of keyword arguments received by this generic function as follows:
:METACLASS argument is not included in the
initialization arguments.If the :DIRECT-SUPERCLASSES argument was received
by this generic function, it is converted into a list of class metaobjects.
This conversion does not affect the structure of the supplied
:DIRECT-SUPERCLASSES argument. For each element in the
:DIRECT-SUPERCLASSES argument:
Otherwise an instance of the class
CLOS:FORWARD-REFERENCED-CLASS is created and used.
The proper name of the newly created forward referenced
class metaobject is set to the element.
A new CLOS:FORWARD-REFERENCED-CLASS
instance is only created when one for the given class name
does not yet exist; otherwise the existing one is reused.
See Implementation of class CLOS:FORWARD-REFERENCED-CLASS in CLISP.
If the class argument is NIL, a new class metaobject is created
by calling the MAKE-INSTANCE generic function with the value of the
:METACLASS argument as its first argument, and the previously
computed initialization arguments. The proper name of the
newly created class metaobject is set to name. The newly created class metaobject is
returned.
If the class argument is a forward referenced class,
CHANGE-CLASS is called to change its class to the value specified
by the :METACLASS argument. The class metaobject is then reinitialized with
the previously initialization arguments. (This is a documented
violation of the general constraint that CHANGE-CLASS may not be
used with class metaobjects.)
The class argument cannot be a forward referenced class. See
Implementation of class CLOS:FORWARD-REFERENCED-CLASS in CLISP.
If the class of the class argument is not the same as the
class specified by the :METACLASS argument, an ERROR is SIGNALed.
Otherwise, the class metaobject class is redefined by calling the
REINITIALIZE-INSTANCE generic function with class and the
initialization arguments. The class argument is then
returned.
Methods
(CLOS:ENSURE-CLASS-USING-CLASS
(class CLASS) name &KEY :METACLASS
:DIRECT-SUPERCLASSES &ALLOW-OTHER-KEYS)This method implements the behavior of the generic
function in the case where the class argument is a class.
This method can be overridden.
(CLOS:ENSURE-CLASS-USING-CLASS
(class CLOS:FORWARD-REFERENCED-CLASS) name &KEY :METACLASS
:DIRECT-SUPERCLASSES &ALLOW-OTHER-KEYS)This method implements the behavior of the generic
function in the case where the class argument is a forward
referenced class.
This method does not exist.
See Implementation of class CLOS:FORWARD-REFERENCED-CLASS in CLISP.
Use the method specialized on NULL instead.
(CLOS:ENSURE-CLASS-USING-CLASS
(class NULL) name &KEY :METACLASS
:DIRECT-SUPERCLASSES &ALLOW-OTHER-KEYS)class argument is NIL.
CLOS:FINALIZE-INHERITANCE(CLOS:FINALIZE-INHERITANCE
class)classThis generic function is called to finalize a class metaobject. This is described in Section 29.3.4, “Class Finalization Protocol”
After CLOS:FINALIZE-INHERITANCE returns, the class metaobject is
finalized and the result of calling CLOS:CLASS-FINALIZED-P on the class metaobject
will be true.
Methods
(CLOS:FINALIZE-INHERITANCE
(class STANDARD-CLASS))(CLOS:FINALIZE-INHERITANCE
(class CLOS:FUNCALLABLE-STANDARD-CLASS))(CLOS:FINALIZE-INHERITANCE
(class CLOS:FORWARD-REFERENCED-CLASS))SIGNALs an ERROR.
MAKE-INSTANCE(MAKE-INSTANCE class &REST
initargs)classinitargsclass.
MAKE-INSTANCE creates and
returns a new instance of the given class. Its behavior and use is
described in the [ANSI CL standard].
Methods
(MAKE-INSTANCE
(class SYMBOL) &REST initargs)MAKE-INSTANCE
recursively on the arguments (FIND-CLASS
class) and initargs.(MAKE-INSTANCE (class
STANDARD-CLASS) &REST initargs)(MAKE-INSTANCE (class
CLOS:FUNCALLABLE-STANDARD-CLASS) &REST initargs)MAKE-INSTANCE described in the [ANSI CL standard] section
7.1
“Object Creation and Initialization”.
ALLOCATE-INSTANCE(ALLOCATE-INSTANCE class
&REST initargs)classinitargsclass
This generic function is called to create a new, uninitialized instance of a class. The interpretation of the concept of an uninitialized instance depends on the class metaobject class.
Before allocating the new instance, CLOS:CLASS-FINALIZED-P is
called to see if class has been finalized. If it has not been
finalized, CLOS:FINALIZE-INHERITANCE is called before the new instance
is allocated.
Methods
(ALLOCATE-INSTANCE
(class STANDARD-CLASS) &REST initargs:INSTANCE. These slots are unbound.
Slots with any other allocation are ignored by this method (no
ERROR is SIGNALed).(ALLOCATE-INSTANCE
(class CLOS:FUNCALLABLE-STANDARD-CLASS)
&REST initargs)This method allocates storage in the instance for
each slot with allocation :INSTANCE. These slots are unbound.
Slots with any other allocation are ignored by this method (no
ERROR is SIGNALed).
The funcallable instance function of the instance is
undefined - the results are undefined if the instance is applied to
arguments before CLOS:SET-FUNCALLABLE-INSTANCE-FUNCTION has been used
to set the funcallable instance function.
(ALLOCATE-INSTANCE
(class BUILT-IN-CLASS) &REST initargs)SIGNALs an ERROR.
CLOS:VALIDATE-SUPERCLASS(CLOS:VALIDATE-SUPERCLASS class
superclass)classsuperclassBOOLEAN.This generic function is called to determine whether
the class superclass is suitable for use as a superclass of
class.
This generic function can be be called by the implementation or user code. It is called during class metaobject initialization and reinitialization, before the direct superclasses are stored. If this generic function returns false, the initialization or reinitialization will signal an error.
Methods
(CLOS:VALIDATE-SUPERCLASS
(class CLASS) (superclass CLASS))This method returns true in three situations:
superclass argument is the class named T,
class argument is the same
as the class of the superclass argument, or
STANDARD-CLASS and the class of the other is
CLOS:FUNCALLABLE-STANDARD-CLASS.In all other cases, this method returns false.
This method can be overridden.
This method also returns true in a fourth situation:
class argument is a subclass
of the class of the superclass argument.
Remarks. Defining a method on CLOS:VALIDATE-SUPERCLASS requires detailed
knowledge of of the internal protocol followed by each of the two
class metaobject classes. A method on CLOS:VALIDATE-SUPERCLASS which returns true
for two different class metaobject classes declares that they are
compatible.
CLOS:COMPUTE-DIRECT-SLOT-DEFINITION-INITARGS(CLOS:COMPUTE-DIRECT-SLOT-DEFINITION-INITARGS class &REST
slot-spec)classslot-specThis generic function determines the initialization
arguments for the direct slot definition for a slot in a class.
It is called during initialization of a class. The resulting
initialization arguments are passed to CLOS:DIRECT-SLOT-DEFINITION-CLASS and then to
MAKE-INSTANCE.
This generic function uses the supplied canonicalized slot specification.
The value of :NAME in the returned initargs is the same as the value
of :NAME in the supplied slot-spec argument.
Methods
(CLOS:COMPUTE-DIRECT-SLOT-DEFINITION-INITARGS
(class STANDARD-CLASS) &REST slot-spec)(CLOS:COMPUTE-DIRECT-SLOT-DEFINITION-INITARGS (class
CLOS:FUNCALLABLE-STANDARD-CLASS) &REST slot-spec)This method returns slot-spec unmodified.
This method can be overridden.
CLOS:DIRECT-SLOT-DEFINITION-CLASS(CLOS:DIRECT-SLOT-DEFINITION-CLASS class &REST
initargs)classinitargsCLOS:DIRECT-SLOT-DEFINITION.
When a class is initialized, each of the canonicalized slot specifications must be converted to a direct slot definition metaobject. This generic function is called to determine the class of that direct slot definition metaobject.
The initargs argument is simply the
canonicalized slot specification for the slot.
Methods
(CLOS:DIRECT-SLOT-DEFINITION-CLASS
(class STANDARD-CLASS) &REST initargs)(CLOS:DIRECT-SLOT-DEFINITION-CLASS (class
CLOS:FUNCALLABLE-STANDARD-CLASS) &REST initargs)These methods return the class CLOS:STANDARD-DIRECT-SLOT-DEFINITION.
These methods can be overridden.
CLOS:COMPUTE-CLASS-PRECEDENCE-LIST(CLOS:COMPUTE-CLASS-PRECEDENCE-LIST
class)classThis generic-function is called to determine the class precedence list of a class.
The result is a list which contains each of class and its
superclasses once and only once. The first element of the list is
class and the last element is the class named T.
All methods on this generic function must compute the class
precedence list as a function of the ordered direct superclasses of
the superclasses of class. The results are undefined if the
rules used to compute the class precedence list depend on any other
factors.
When a class is finalized, CLOS:FINALIZE-INHERITANCE calls this
generic function and associates the returned value with the class metaobject.
The value can then be accessed by calling CLOS:CLASS-PRECEDENCE-LIST.
The list returned by this function will not be mutated by the implementation. The results are undefined if a portable program mutates the list returned by this function.
Methods
(CLOS:COMPUTE-CLASS-PRECEDENCE-LIST (class
CLASS))This method computes the class precedence list according to the rules described in the [ANSI CL standard] section 4.3.5 “Determining the Class Precedence List”.
This method SIGNALs an ERROR if class or any of its superclasses
is a forward referenced class.
This method can be overridden.
CLOS:COMPUTE-SLOTS(CLOS:COMPUTE-SLOTS class)
classThis generic function computes a set of effective
slot definition metaobjects for the class class. The result is a list of effective slot definition metaobjects:
one for each slot that will be accessible in instances of class.
This generic function proceeds in 3 steps:
The first step collects the full set of direct slot
definitions from the superclasses of class.
The direct slot definitions are then collected into
individual lists, one list for each slot name associated with any of
the direct slot definitions. The slot names are compared with
EQL. Each such list is then sorted into class precedence list
order. Direct slot definitions coming from classes earlier in the
class precedence list of class appear before those coming from
classes later in the class precedence list. For each slot name, the
generic function CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION is called to compute an effective slot
definition. The result of CLOS:COMPUTE-SLOTS is a list of these
effective slot definitions, in unspecified order.
In the final step, the location for each effective slot definition is set. This is done by specified around-methods; portable methods cannot take over this behavior. For more information on the slot definition locations, see Section 29.10.1, “Instance Structure Protocol”.
The list returned by this function will not be mutated by the implementation. The results are undefined if a portable program mutates the list returned by this function.
Methods
(CLOS:COMPUTE-SLOTS
(class STANDARD-CLASS))(CLOS:COMPUTE-SLOTS
(class CLOS:FUNCALLABLE-STANDARD-CLASS)}These methods implement the specified behavior of the generic function.
These methods can be overridden.
(CLOS:COMPUTE-SLOTS
:AROUND (class STANDARD-CLASS))(CLOS:COMPUTE-SLOTS :AROUND
(class CLOS:FUNCALLABLE-STANDARD-CLASS))CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION(CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION class name direct-slot-definitions)
classnamedirect-slot-definitionsThis generic function determines the effective slot
definition for a slot in a class. It is called by CLOS:COMPUTE-SLOTS
once for each slot accessible in instances of class.
This generic function uses the supplied list of direct slot definition metaobjects to compute the inheritance of slot properties for a single slot. The returned effective slot definition represents the result of computing the inheritance. The name of the new effective slot definition is the same as the name of the direct slot definitions supplied.
The class of the effective slot definition metaobject is determined by calling
CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS. The effective slot definition is then created by
calling MAKE-INSTANCE. The initialization arguments passed in this
call to MAKE-INSTANCE are used to initialize the new effective slot definition metaobject.
See Section 29.4, “Slot Definitions” for details.
Methods
(CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION (class
STANDARD-CLASS) name direct-slot-definitions)(CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION (class
CLOS:FUNCALLABLE-STANDARD-CLASS) name direct-slot-definitions)This method implements the inheritance and defaulting of slot options following the rules described in the [ANSI CL standard] section 7.5.3 “Inheritance of Slots and Options”.
This method can be extended, but the value returned by the extending method must be the value returned by this method.
The initialization arguments that are passed
to CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS and MAKE-INSTANCE are computed through a call to
CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGS. It is the CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGS method that
implements the inheritance rules.
CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGS(CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGS class direct-slot-definitions)
classdirect-slot-definitionsThis generic function determines the initialization
arguments for the effective slot definition for a slot in a class.
It is called by CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION. The resulting initialization arguments
are passed to CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS and then to MAKE-INSTANCE.
This generic function uses the supplied list of direct slot definition metaobjects to
compute the inheritance of slot properties for a single slot. The
returned effective slot definition initargs represent the result of
computing the inheritance. The value of :NAME in the returned
initargs is the same as the name of the direct slot definitions
supplied.
Methods
(CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGS
(class STANDARD-CLASS) direct-slot-definitions)(CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGS (class
CLOS:FUNCALLABLE-STANDARD-CLASS) direct-slot-definitions)This method implements the inheritance and defaulting of slot options following the rules described in the [ANSI CL standard] section 7.5.3 “Inheritance of Slots and Options”.
This method can be extended.
CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS(CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS class &REST
initargs)classinitargsCLOS:EFFECTIVE-SLOT-DEFINITION-CLASS.
CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION to
determine the class of the resulting effective slot definition metaobject. The initargs
argument is the set of initialization arguments and values that will
be passed to MAKE-INSTANCE when the effective slot definition metaobject is created.
Methods
(CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS
(class STANDARD-CLASS) &REST initargs)(CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS (class
CLOS:FUNCALLABLE-STANDARD-CLASS) &REST initargs)These methods return the class CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION.
These methods can be overridden.
CLOS:COMPUTE-DEFAULT-INITARGS(CLOS:COMPUTE-DEFAULT-INITARGS
class)classThis generic-function is called to determine the default initialization arguments for a class.
The result is a list of canonicalized default initialization arguments, with no duplication among initialization argument names.
All methods on this generic function must compute the default initialization arguments as a function of only:
class,
andThe results are undefined if the rules used to compute the default initialization arguments depend on any other factors.
When a class is finalized, CLOS:FINALIZE-INHERITANCE calls this
generic function and associates the returned value with the class metaobject.
The value can then be accessed by calling
CLOS:CLASS-DEFAULT-INITARGS.
The list returned by this function will not be mutated by the implementation. The results are undefined if a portable program mutates the list returned by this function.
Methods
(CLOS:COMPUTE-DEFAULT-INITARGS
(class STANDARD-CLASS))(CLOS:COMPUTE-DEFAULT-INITARGS
(class CLOS:FUNCALLABLE-STANDARD-CLASS))These methods compute the default initialization arguments according to the rules described in the [ANSI CL standard] section 7.1.3 “Defaulting of Initialization Arguments”.
These methods signal an error if class or any of its
superclasses is a forward referenced class.
These methods can be overridden.
CLOS:ADD-DIRECT-SUBCLASS(CLOS:ADD-DIRECT-SUBCLASS superclass
subclass)superclasssubclassThis generic function is called to maintain a set of
backpointers from a class to its direct subclasses. This generic
function adds subclass to the set of direct subclasses of
superclass.
When a class is initialized, this generic function is called once for each direct superclass of the class.
When a class is reinitialized, this generic function is
called once for each added direct superclass of the class. The
generic function CLOS:REMOVE-DIRECT-SUBCLASS is called once for each
deleted direct superclass of the class.
Methods
(CLOS:ADD-DIRECT-SUBCLASS
(superclass CLASS) (subclass CLASS))No behavior is specified for this method beyond that which is specified for the generic function.
This method cannot be overridden unless the following methods are overridden as well:
CLOS:REMOVE-DIRECT-SUBCLASS(CLOS:REMOVE-DIRECT-SUBCLASS superclass
subclass)superclasssubclassThis generic function is called to maintain a set of
backpointers from a class to its direct subclasses. It removes
subclass from the set of direct subclasses of superclass. No
ERROR is SIGNALed if subclass is not in this set.
Whenever a class is reinitialized, this generic function is called once with each deleted direct superclass of the class.
Methods
(CLOS:REMOVE-DIRECT-SUBCLASS
(superclass CLASS) (subclass CLASS))No behavior is specified for this method beyond that which is specified for the generic function.
This method cannot be overridden unless the following methods are overridden as well:
| These notes document CLISP version 2.49 | Last modified: 2010-07-07 |