Previous Section Next Section Table of Contents Glossary Index

Chapter 4. Using Clozure CL

4.3. Advising

The advise macro can be thought of as a more general version of trace. It allows code that you specify to run before, after, or around a given function, for the purpose of changing the behavior of the function. Each piece of added code is called a piece of advice. Each piece of advice has a unique name, so that you can have multiple pieces of advice on the same function, including multiple :before, :after, and :around pieces of advice.

The :name and :when keywords serve to identify the piece of advice. A later call to advise with the same values of :name and :when will replace the existing piece of advice; a call with different values will not.

[Macro]

advise spec form &key when name
Add a piece of advice to the function or method specified by spec according to form.

Arguments and Values:

spec--- A specification of the function on which to put the advice. This is either a symbol that is the name of a function or generic function, or an expression of the form (setf symbol), or a specific method of a generic function in the form (:method symbol {qualifiers} (specializer {specializer})).

form--- A form to execute before, after, or around the advised function. The form can refer to the variable arglist that is bound to the arguments with which the advised function was called. You can exit from form with (return).

name--- A name that identifies the piece of advice.

when--- An argument that specifies when the piece of advice is run. There are three allowable values. The default is :before, which specifies that form is executed before the advised function is called. Other possible values are :after, which specifies that form is executed after the advised function is called, and :around, which specifies that form is executed around the call to the advised function. Use (:do-it) within form to indicate invocation of the original definition.

Examples:

The function foo, already defined, does something with a list of numbers. The following code uses a piece of advice to make foo return zero if any of its arguments is not a number. Using :around advice, you can do the following:

(advise foo (if (some #'(lambda (n) (not (numberp n))) arglist)
	      0
	      (:do-it))
	:when :around :name :zero-if-not-nums)
	

To do the same thing using a :before piece of advice:

(advise foo (if (some #'(lambda (n) (not (numberp n))) arglist)
	      (return 0))
	:when :before :name :zero-if-not-nums)
	

[Macro]

unadvise spec &key when name
Remove the piece or pieces of advice matching spec, when, and name.

Description:

The unadvise macro removes the piece or pieces of advice matching spec, when, and name. When the value of spec is t and the values of when and name are nil, unadvise removes every piece of advice; when spec is t, the argument when is nil, and name is non-nil, unadvise removes all pieces of advice with the given name.

Arguments and Values:

The arguments have the same meaning as in advise.

[Macro]

advisedp spec &key when name
Return a list of the pieces of advice matching spec, when, and name.

Description:

The advisedp macro returns a list of existing pieces of advice that match spec, when, and name. When the value of spec is t and the values of when and name are nil, advisedp returns all existing pieces of advice.

Arguments and Values:

The arguments have the same meaning as in advise.


Previous Section Next Section Table of Contents Glossary Index