Next: Inheritance of Methods, Previous: Keyword Arguments in Generic Functions and Methods, Up: Generic Functions and Methods
When a generic function is called with particular arguments, it must determine the code to execute. This code is called the effective method for those arguments. The effective method is a combination of the applicable methods in the generic function that calls some or all of the methods.
If a generic function is called and no methods are
applicable, the generic function no-applicable-method
is invoked, with the results from that call being used as the
results of the call to the original generic function. Calling
no-applicable-method
takes precedence over checking for acceptable
keyword arguments; see Section 7.6.5 (Keyword Arguments in Generic Functions and Methods).
When the effective method has been determined, it is invoked with the same arguments as were passed to the generic function. Whatever values it returns are returned as the values of the generic function.
The effective method is determined by the following three-step procedure:
This step is described in Section 7.6.2 (Introduction to Methods).
To compare the precedence of two methods, their parameter specializers
are examined in order. The default examination order is from left to
right, but an alternative order may be specified by the
:argument-precedence-order option to defgeneric
or to any of
the other operators that specify generic function options.
The corresponding parameter specializers from each method are compared. When a pair of parameter specializers agree, the next pair are compared for agreement. If all corresponding parameter specializers agree, the two methods must have different qualifiers; in this case, either method can be selected to precede the other. For information about agreement, see Section 7.6.3 (Agreement on Parameter Specializers and Qualifiers).
If some corresponding parameter specializers do not agree, the first pair of parameter specializers that do not agree determines the precedence. If both parameter specializers are classes, the more specific of the two methods is the method whose parameter specializer appears earlier in the class precedence list of the corresponding argument. Because of the way in which the set of applicable methods is chosen, the parameter specializers are guaranteed to be present in the class precedence list of the class of the argument.
If just one of a pair of corresponding parameter specializers is (eql
object)
,
the method with that parameter specializer precedes the
other method. If both parameter specializers are eql
expressions, the
specializers must agree (otherwise the two methods would
not both have been applicable to this argument).
The resulting list of applicable methods has the most specific method first and the least specific method last.
In the simple case—if standard method combination is used and all
applicable methods are primary methods—the
effective method is the most specific method.
That method can call the next most specific
method by using the function call-next-method
. The method that
call-next-method
will call is referred to as the
next method. The predicate next-method-p
tests whether a next
method exists. If call-next-method
is called and there is no
next most specific method, the generic function no-next-method
is invoked.
In general, the effective method is some combination of the applicable
methods. It is described by a form that contains calls to some or
all of the applicable methods, returns the value or values that will
be returned as the value or values of the generic function, and
optionally makes some of the methods accessible by means of
call-next-method
.
The role of each method in the effective method is determined by its qualifiers and the specificity of the method. A qualifier serves to mark a method, and the meaning of a qualifier is determined by the way that these marks are used by this step of the procedure. If an applicable method has an unrecognized qualifier, this step signals an error and does not include that method in the effective method.
When standard method combination is used together with qualified methods, the effective method is produced as described in Section 7.6.6.2 (Standard Method Combination).
Another type of method combination can be specified by using the
:method-combination option of defgeneric
or
of any of the other operators that specify generic function options. In
this way this step of the procedure can be customized.
New types of method combination can be defined by using
the define-method-combination
macro.
Standard method combination is supported by the class standard-generic-function
.
It is used if no other type of method
combination is specified or if the built-in method combination type
standard is specified.
Primary methods define the main action of the effective method, while auxiliary methods modify that action in one of three ways. A primary method has no method qualifiers.
An auxiliary method is a method whose qualifier is :before, :after, or :around. Standard method combination allows no more than one qualifier per method; if a method definition specifies more than one qualifier per method, an error is signaled.
call-next-method
).
The semantics of standard method combination is as follows:
call-next-method
can be used to call the next method. When the next
method returns, the around method can execute more code,
perhaps based on the returned value or values.
The generic function no-next-method
is invoked if call-next-method
is used and
there is no applicable method to call. The function next-method-p
may be used to determine whether a next method exists.
call-next-method
,
the next most specific around method
is called, if one is applicable. If there are no around methods
or if call-next-method
is called by the least
specific around method, the other methods are called as
follows:
call-next-method
is used in a
before method.
call-next-method
may be used to call
the next most specific primary method. When that method returns, the
previous primary method can execute more code, perhaps based on the
returned value or values. The generic function no-next-method
is invoked if call-next-method
is used and there are no more
applicable primary methods. The function next-method-p
may be
used to determine whether a next method exists. If call-next-method
is not used, only the most specific primary method is called.
call-next-method
is used in an
after method.
call-next-method
in the least specific around method are
those returned by the most specific primary method.
In standard method combination, if there is an applicable method but no applicable primary method, an error is signaled.
The before methods are run in most-specific-first order while the after methods are run in least-specific-first order. The design rationale for this difference can be illustrated with an example. Suppose class C1 modifies the behavior of its superclass, C2, by adding before methods and after methods. Whether the behavior of the class C2 is defined directly by methods on C2 or is inherited from its superclasses does not affect the relative order of invocation of methods on instances of the class C1. Class C1's before method runs before all of class C2's methods. Class C1's after method runs after all of class C2's methods.
By contrast, all around methods run before any other methods run. Thus a less specific around method runs before a more specific primary method.
If only primary methods are used and if call-next-method
is not
used, only the most specific method is invoked; that is, more specific
methods shadow more general ones.
The macro define-method-combination
defines new forms of method
combination. It provides a mechanism for customizing the production
of the effective method. The default procedure for producing an
effective method is described in Section 7.6.6.1 (Determining the Effective Method).
There are two forms of
define-method-combination
. The short form is a simple facility while
the long form is more powerful and more verbose. The long form
resembles defmacro
in that the body is an expression that
computes a Lisp form; it provides mechanisms for implementing
arbitrary control structures within method combination and for
arbitrary processing of method qualifiers.
The object system provides a set of built-in method combination types. To
specify that a generic function is to use one of these method
combination types, the name of the method combination type is given as
the argument to the :method-combination option to
defgeneric
or to the :method-combination option to any of the
other operators that specify generic function options.
The names of the built-in method combination types are listed in the next figure.
The semantics of the standard built-in method combination type is described in Section 7.6.6.2 (Standard Method Combination). The other built-in method combination types are called simple built-in method combination types.
The simple built-in method combination types act as though they were
defined by the short form of define-method-combination
.
They recognize two roles for methods:
call-next-method
and next-method-p
is supported in around methods.
and
recognizes methods whose sole qualifier is
and
; these are primary methods. Use of the functions
call-next-method
and next-method-p
is not supported
in primary methods.
The semantics of the simple built-in method combination types is as follows:
call-next-method
can be used to call the next method.
The generic function no-next-method
is invoked if
call-next-method
is used and there is no applicable method to call.
The function next-method-p
may be used to determine whether a
next method exists. When the next method returns,
the around method can execute more code,
perhaps based on the returned value or values.
call-next-method
,
the next most specific around method is
called, if one is applicable. If there are no around methods
or if call-next-method
is called by the least specific
around method, a Lisp form derived from the name of the built-in
method combination type and from the list of applicable primary
methods is evaluated to produce the value of the generic function.
Suppose the name of the method combination type is operator
and the call to the generic function is of the form
(generic-function a1... an)
(operator 〈 M1a1... an〉...〈 Mk a1... an〉)
or
,
the expression 〈 Mi a1... an〉 is
evaluated only if 〈 Mj a1... an〉,
1≤ j<i, returned nil
.
The simple built-in method combination types require exactly one qualifier per method. An error is signaled if there are applicable methods with no qualifiers or with qualifiers that are not supported by the method combination type. An error is signaled if there are applicable around methods and no applicable primary methods.