[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A method contains a method procedure and a sequence of parameter specializers that specify when the given method is applicable.
A method is not a procedure and cannot be invoked as a procedure. Methods are invoked by the effective method procedure when a generic procedure is called.
5.1 Method Datatype 5.2 Method Syntax 5.3 Chained Methods 5.4 Computed Methods
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following procedures are used to construct and inspect methods.
<object>
.
After the returned method is stored in a generic procedure, Procedure is called by the effective method procedure of the generic procedure when the generic procedure is called with arguments satisfying specializers. In simple cases, when no method combination occurs, procedure is the effective method procedure.
#t
iff object is a method, otherwise returns
#f
.
method-applicable?
determines whether method would be
applicable if the given arguments had the classes specified by
classes. It returns #t
if each element of classes is
a subclass of the corresponding specializer of method, and
#f
otherwise.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following syntactic forms greatly simplify the definition of methods, and of adding them to generic procedures.
lambda
special form, except that the
required parameters may have associated specializers. A parameter with
an associated specializer is written as a list of two elements: the
first element is the parameter's name, and the second element is an
expression that evaluates to a class.
Lambda-list must contain at least one required parameter, and at least one required parameter must be specialized.
A define-method
special form expands into the following:
(add-method generic-procedure (make-method (list specializer ...) (lambda (call-next-method . stripped-lambda-list) body ...))) |
where stripped-lambda-list is lambda-list with the
specialized parameters replaced by their names, and the
specializers are the corresponding expressions from the
specialized parameters. If necessary, the specializers are
interspersed with references to <object>
in order to make them
occur in the correct position in the sequence.
For example,
(define-method add ((x <integer>) (y <rational>)) ...) |
expands into
(add-method add (make-method (list <integer> <rational>) (lambda (call-next-method x y) ...))) |
Note that the list of specializers passed to make-method
will
correspond to the required parameters of the method; the specializer
corresponding to a non-specialized required parameter is
<object>
.
Further note that, within the body of a define-method
special
form, the free variable call-next-method
is bound to a
"call-next-method" procedure (see make-chained-method
for
details). If the define-method
body refers to this variable, the
defined method is a chained method, otherwise it is an ordinary method.
lambda
evaluates to an anonymous procedure. Lambda-list
and body have exactly the same syntax and semantics as the
corresponding parts of define-method
. Note that the following
are completely equivalent:
(define-method g ((a <foo>) b) (cons b a)) (add-method g (method ((a <foo>) b) (cons b a))) (add-method g (make-method (list <foo>) (lambda (a b) (cons b a)))) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Sometimes it is useful to have a method that adds functionality to existing methods. Chained methods provide a mechanism to accomplish this. A chained method, when invoked, can call the method that would have been called had this method not been defined: it is passed a procedure that will call the inherited method. The chained method can run arbitrary code both before and after calling the inherited method.
#t
if object is a chained method, otherwise returns
#f
. Note that every chained method satisfies method?
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A computed method is a powerful mechanism that provides the ability to generate methods "on the fly". A computed method is like an ordinary method, except that its procedure is called during method combination, and is passed the classes of the arguments in place of the arguments themselves. Based on these classes, the computed method returns an ordinary method, which is combined in the usual way.
Note that computed methods and computed EMPs both satisfy the
predicate method?
. They are not really methods in that they
cannot be combined with other methods to form an effective method
procedure; however, they are treated as methods by procedures such as
add-method
and method-specializers
.
make-method
or
make-chained-method
). The returned method's specializers must be
restrictions of specializers, i.e. each specializer in the
returned method must be a subclass of the corresponding specializer in
specializers. In the usual case, the returned method's
specializers are the same as specializers.
make-method
on specializers and the returned procedure.
#f
, which means that the computed method declines to generate a
method.
#t
if object is a computed method, otherwise
returns #f
.
A computed EMP takes the computed-method mechanism one step
further. A computed EMP is like a computed method, except that it
returns an effective method procedure rather than a method.
compute-effective-method-procedure
tries each of the applicable
computed EMPs, and if exactly one of them returns an EMP, that
is the resulting effective method procedure.
#f
.
Key is an arbitrary object that is used to identify the computed
EMP. The key is used by add-method
and
delete-method
to decide whether two computed EMPs are
the same; they are the same if their keys are equal?
. This
is necessary because a generic procedure may have more than one computed
EMP with the same specializers.
#t
if object is a computed EMP, otherwise
returns #f
.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |