The reader generic functions which simply return information associated with method metaobjects are presented together here in the format described in Section 29.3.3, “Introspection: Readers for class metaobjects”.
Each of these reader generic functions have the same syntax,
accepting one required argument called method, which must be a
method metaobject; otherwise, an ERROR is SIGNALed. An ERROR is also SIGNALed
if the method 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.
CLOS:METHOD-SPECIALIZERS(CLOS:METHOD-SPECIALIZERS method)Returns a list of the specializers of method. This value is a
list of specializer metaobjects. This is the value of the
:SPECIALIZERS initialization argument that was associated with the
method during initialization.
METHOD-QUALIFIERS(METHOD-QUALIFIERS method)Returns a (possibly empty) list of the qualifiers of method.
This value is a list of non-NIL atoms. This is the defaulted value of
the :QUALIFIERS initialization argument that was associated with the
method during initialization.
CLOS:METHOD-LAMBDA-LIST(CLOS:METHOD-LAMBDA-LIST method)Returns the (unspecialized) lambda list of method. This value
is a Common Lisp lambda list. This is the value of the :LAMBDA-LIST
initialization argument that was associated with the method during
initialization.
CLOS:METHOD-GENERIC-FUNCTION(CLOS:METHOD-GENERIC-FUNCTION method)Returns the generic function that method is currently
connected to, or NIL if it is not currently connected to any generic
function. This value is either a generic function metaobject or NIL.
When a method is first created it is not connected to any generic
function. This connection is maintained by the generic functions
ADD-METHOD and REMOVE-METHOD.
CLOS:METHOD-FUNCTION(CLOS:METHOD-FUNCTION method)Returns the method function of method. This is the
value of the :FUNCTION initialization argument that was associated
with the method during initialization.
The specified methods for the method metaobject readers
(CLOS:METHOD-SPECIALIZERS
(method STANDARD-METHOD))(METHOD-QUALIFIERS
(method STANDARD-METHOD))(CLOS:METHOD-LAMBDA-LIST
(method STANDARD-METHOD))(CLOS:METHOD-FUNCTION
(method STANDARD-METHOD))(CLOS:METHOD-GENERIC-FUNCTION
(method STANDARD-METHOD))No behavior is specified for this method beyond that which is specified for the generic function.
The value returned by this method is maintained by
and
ADD-METHOD(STANDARD-GENERIC-FUNCTION
STANDARD-METHOD).REMOVE-METHOD(STANDARD-GENERIC-FUNCTION
STANDARD-METHOD)
DEFMETHODThe evaluation or execution of a DEFMETHOD form requires first
that the body of the method be converted to a method function.
This process is described
below.
The result of this process is a method function and a set of additional
initialization arguments to be used when creating the new method.
Given these two values, the evaluation or execution of a DEFMETHOD
form proceeds in three steps.
The first step ensures the existence of a generic function with
the specified name. This is done by calling the function ENSURE-GENERIC-FUNCTION.
The first argument in this call is the generic function name specified
in the DEFMETHOD form.
The second step is the creation of the new method metaobject by calling
MAKE-INSTANCE. The class of the new method metaobject is determined by calling
CLOS:GENERIC-FUNCTION-METHOD-CLASS on the result of the call to ENSURE-GENERIC-FUNCTION from the
first step.
The initialization arguments received by the call to MAKE-INSTANCE
are as follows:
:QUALIFIERS initialization
argument is a list of the qualifiers which appeared in the DEFMETHOD
form. No special processing is done on these values. The order of the
elements of this list is the same as in the DEFMETHOD form.
:LAMBDA-LIST initialization
argument is the unspecialized lambda list from the DEFMETHOD form.
:SPECIALIZERS initialization
argument is a list of the specializers for the method. For specializers
which are classes, the specializer is the class metaobject itself. In
the case of EQL specializers, it will be an CLOS:EQL-SPECIALIZER
metaobject obtained by calling CLOS:INTERN-EQL-SPECIALIZER on the result of
evaluating the EQL specializer form in the lexical environment of the
DEFMETHOD form.:FUNCTION initialization
argument is the method function.The value of the :DECLARATIONS initialization
argument is a list of the declaration specifiers from the DEFMETHOD form.
If there are no declarations in the macro form, this initialization argument
either does not appear, or appears with a value of the empty list.
No :DECLARATIONS initialization argument is
provided, because method initialization does not support a :DECLARATIONS
argument, and because the method function is already completely provided
through the :FUNCTION initialization argument.
:DOCUMENTATION initialization
argument is the documentation string from the DEFMETHOD form. If
there is no documentation string in the macro form this initialization
argument either does not appear, or appears with a value of false.
In the third step, ADD-METHOD is called to add the newly created
method to the set of methods associated with the generic function metaobject.
The result of the call to ADD-METHOD is returned as the result
of evaluating or executing the DEFMETHOD form.
An example showing a typical DEFMETHOD form and a sample
expansion is shown in the following example:
An example DEFMETHOD form and one possible correct
expansion. In the expansion, method-lambda
is the result of calling CLOS:MAKE-METHOD-LAMBDA as described in
Section 29.6.3.1.1, “Processing Method Bodies”.
The initargs appearing after :FUNCTION are assumed to be additional
initargs returned from the call to CLOS:MAKE-METHOD-LAMBDA.
(defmethod move :before ((p position) (l (eql 0))
&OPTIONAL (visiblyp t)
&KEY color)
(set-to-origin p)
(when visiblyp (show-move p 0 color)))
(let ((#:g001 (ensure-generic-function 'move)))
(add-method #:g001
(make-instance (generic-function-method-class #:g001)
:qualifiers '(:before)
:specializers (list (find-class 'position)
(intern-eql-specializer 0))
:lambda-list '(p l &OPTIONAL (visiblyp t)
&KEY color)
:function (function method-lambda)
'additional-initarg-1 't
'additional-initarg-2 '39)))
The processing of the method body for this method is shown below.
Before a method can be created, the list of forms comprising the method body must be converted to a method function. This conversion is a two step process.
The body of methods can also appear in the
:METHOD option of DEFGENERIC forms. Initial methods are
not considered by any of the protocols specified in this document.
During macro-expansion of the DEFMETHOD macro shown in
the previous example code
similar to this would be run to produce the method lambda and
additional initargs. In this example, environment is the macroexpansion
environment of the DEFMETHOD macro form.
(let ((gf (ensure-generic-function 'move)))
(make-method-lambda
gf
(class-prototype (generic-function-method-class gf))
'(lambda (p l &OPTIONAL (visiblyp t) &KEY color)
(set-to-origin p)
(when visiblyp (show-move p 0 color)))
environment))
The first step occurs during macro-expansion of the macro form. In this step, the method lambda list, declarations and body are converted to a lambda expression called a method lambda . This conversion is based on information associated with the generic function definition in effect at the time the macro form is expanded.
The generic function definition is obtained by calling ENSURE-GENERIC-FUNCTION with
a first argument of the generic function name specified in the macro form.
The :LAMBDA-LIST keyword argument is not passed in this call.
Given the generic function, production of the method lambda
proceeds by calling CLOS:MAKE-METHOD-LAMBDA.
The first argument in this call is the generic function obtained as
described above.
The second argument is the result of calling CLOS:CLASS-PROTOTYPE on the
result of calling CLOS:GENERIC-FUNCTION-METHOD-CLASS on the generic function.
The third argument is a lambda expression formed from the method lambda list,
declarations and body.
The fourth argument is the macro-expansion environment of the macro
form; this is the value of the &ENVIRONMENT argument to the
DEFMETHOD macro.
The generic function CLOS:MAKE-METHOD-LAMBDA returns two values.
The first is the method lambda itself.
The second is a list of initialization arguments and values. These are
included in the initialization arguments when the method is created.
In the second step, the method lambda is converted to a function
which properly captures the lexical scope of the macro form. This is
done by having the method lambda appear in the macro-expansion as the
argument of the FUNCTION special form. During the subsequent
evaluation of the macro-expansion, the result of the FUNCTION special
form is the method function.
See The generic function CLOS:MAKE-METHOD-LAMBDA is not implemented.
An example of creating a generic function and a method metaobject, and then adding the method to the generic function is shown below. This example is comparable to the method definition shown above:
(let* ((gf (make-instance 'standard-generic-function
:lambda-list '(p l &OPTIONAL visiblyp &KEY)))
(method-class (generic-function-method-class gf)))
(multiple-value-bind (lambda initargs)
(make-method-lambda
gf
(class-prototype method-class)
'(lambda (p l &OPTIONAL (visiblyp t) &KEY color)
(set-to-origin p)
(when visiblyp (show-move p 0 color)))
nil)
(add-method gf
(apply #'make-instance method-class
:function (compile nil lambda)
:specializers (list (find-class 'position)
(intern-eql-specializer 0))
:qualifiers ()
:lambda-list '(p l &OPTIONAL (visiblyp t)
&KEY color)
initargs))))
Methods created through DEFMETHOD have a faster calling
convention than methods created through a portable MAKE-INSTANCE
invocation.
A method metaobject can be created by calling MAKE-INSTANCE.
The initialization arguments establish the definition of the method.
A method metaobject cannot be redefined;
calling REINITIALIZE-INSTANCE SIGNALs an ERROR.
Initialization of a method metaobject must be done by calling MAKE-INSTANCE
and allowing it to call INITIALIZE-INSTANCE. Portable programs must
not
INITIALIZE-INSTANCE directly to
initialize a method metaobject;SHARED-INITIALIZE directly to
initialize a method metaobject;CHANGE-CLASS to change the class of any
method metaobject or to turn a non-method object into a method metaobject.
Since metaobject classes may not be redefined,
no behavior is specified for the result of calls to
UPDATE-INSTANCE-FOR-REDEFINED-CLASS on method metaobjects.
Since the class of a method metaobject cannot be changed,
no behavior is specified for the result of calls to
UPDATE-INSTANCE-FOR-DIFFERENT-CLASS on method metaobjects.
During initialization, each initialization argument is checked for errors and then associated with the method metaobject. The value can then be accessed by calling the appropriate accessor as shown in Table 29.5, “Initialization arguments and accessors for method 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. The section ends with a set of restrictions on portable methods affecting method metaobject initialization.
In these descriptions, the phrase “this argument defaults to
value” means that when that initialization argument is not
supplied, initialization 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 method metaobject classes. Portable programs
are free to define default initialization arguments for portable
subclasses of the class METHOD.
:QUALIFIERS argument is a list of method
qualifiers. An ERROR is SIGNALed if this value is not a proper list, or if
any element of the list is not a non-null atom. This argument
defaults to the empty list.:LAMBDA-LIST argument is the unspecialized
lambda list of the method. An ERROR is SIGNALed if this value is not a
proper lambda list. If this value is not supplied, an ERROR is SIGNALed.
:SPECIALIZERS argument is a list of the
specializer metaobjects for the method. An ERROR is SIGNALed if this value
is not a proper list, or if the length of the list differs from the
number of required arguments in the :LAMBDA-LIST argument, or if
any element of the list is not a specializer metaobject. If this
value is not supplied, an ERROR is SIGNALed.:FUNCTION argument is a method function. It
must be compatible with the methods on CLOS:COMPUTE-EFFECTIVE-METHOD
defined for this class of method and generic function with which it
will be used. That is, it must accept the same number of arguments
as all uses of CALL-METHOD that will call it supply. (See
CLOS:COMPUTE-EFFECTIVE-METHOD and CLOS:MAKE-METHOD-LAMBDA for more information.)
An ERROR is SIGNALed if this argument is not supplied.CLOS:STANDARD-ACCESSOR-METHOD, the :SLOT-DEFINITION
initialization argument must be provided. Its value is the direct
slot definition metaobject which defines this accessor method. An ERROR is SIGNALed if the value
is not an instance of a subclass of CLOS:DIRECT-SLOT-DEFINITION.:DOCUMENTATION argument is a string or NIL.
An ERROR is SIGNALed if this value is not a string or NIL. 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 method metaobject. These values can then be accessed by calling the corresponding generic function. The correspondences are as follows:
Table 29.5. Initialization arguments and accessors for method metaobjects
| Initialization Argument | Generic Function |
|---|---|
:QUALIFIERS | METHOD-QUALIFIERS |
:LAMBDA-LIST | CLOS:METHOD-LAMBDA-LIST |
:SPECIALIZERS | CLOS:METHOD-SPECIALIZERS |
:FUNCTION | CLOS:METHOD-FUNCTION |
:SLOT-DEFINITION | CLOS:ACCESSOR-METHOD-SLOT-DEFINITION |
:DOCUMENTATION | DOCUMENTATION |
It is not specified which methods provide the initialization behavior described above. Instead, the information needed to allow portable programs to specialize this behavior is presented in as a set of restrictions on the methods a portable program can define. The model is that portable initialization methods have access to the method 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 METHOD. Other portable
methods on these generic functions are not affected by these
restrictions.
SHARED-INITIALIZE or REINITIALIZE-INSTANCE.For INITIALIZE-INSTANCE:
The results are undefined if any of these restrictions are violated.
CLOS:EXTRACT-LAMBDA-LIST(CLOS:EXTRACT-LAMBDA-LIST specialized-lambda-list)
specialized-lambda-listDEFMETHOD.
This function takes a specialized lambda list and returns the lambda list with the specializers removed. This is a non-destructive operation. Whether the result shares any structure with the argument is unspecified.
If the specialized-lambda-list argument does not have legal syntax,
an ERROR is SIGNALed. This syntax checking does not check the syntax of the
actual specializer names, only the syntax of the lambda list and
where the specializers appear.
(CLOS:EXTRACT-LAMBDA-LIST'((p position))) ⇒(P)(CLOS:EXTRACT-LAMBDA-LIST'((p position) x y)) ⇒(P X Y)(CLOS:EXTRACT-LAMBDA-LIST'(a (b (eql x)) c&RESTi)) ⇒(A B C&OPTIONALI)
CLOS:EXTRACT-SPECIALIZER-NAMES(CLOS:EXTRACT-SPECIALIZER-NAMES
specialized-lambda-list)specialized-lambda-listDEFMETHOD.
This function takes a specialized lambda list and returns its specializer names. This is a non-destructive operation. Whether the result shares structure with the argument is unspecified.
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.
The result of this function will be a list with a
number of elements equal to the number of required arguments in
specialized-lambda-list. Specializers are defaulted to the symbol T.
If the specialized-lambda-list argument does not have legal
syntax, an ERROR is SIGNALed. This syntax checking does not check the syntax
of the actual specializer names, only the syntax of the lambda list
and where the specializers appear.
(CLOS:EXTRACT-SPECIALIZER-NAMES'((p position))) ⇒(POSITION)(CLOS:EXTRACT-SPECIALIZER-NAMES'((p position) x y)) ⇒(POSITION T T)(CLOS:EXTRACT-SPECIALIZER-NAMES'(a (b (eql x)) c&RESTi)) ⇒(T (EQL X) T)
| These notes document CLISP version 2.49.93+ | Last modified: 2018-02-19 |