6.3 The Advice Facility
defadvice
and related advising constructs.;; Define a function that adds 1 to its argument. > (defun add-one (x) (+ x 1)) ADD-ONE> (add-one 3) ; 3+1 = 4 4
;; Put some advice on it that gives a default value for the ;; argument. > (defadvice (add-one default-to-zero) (&optional (x 0)) (advice-continue x)) #<Advice DEFAULT-TO-ZERO B00D37
> (add-one) ; No argument supplied, so 0+1 = 1 1
;; Put some more advice on to double the result. > (defadvice (add-one double-result) (&rest args) (* 2 (apply-advice-continue args))) #<Advice DOUBLE-RESULT B261BF
> (add-one) ; (default 0+1)*2 = 2 2
> (add-one 5) ; (5+1)*2 = 12 12
;; See what is there now. > (describe-advice 'add-one) Advice DOUBLE-RESULT: #<Interpreted-Function (:ADVICE ADD-ONE DOUBLE-RESULT) B362D7> Advice DEFAULT-TO-ZERO: #<Interpreted-Function (:ADVICE ADD-ONE DEFAULT-TO-ZERO) B3619F> Original definition: #<Interpreted-Function (NAMED-LAMBD ADD-ONE (X) (BLOCK ADD-ONE (+ X 1))) AF1A57> NIL
;; Get rid of one of the pieces of advice. > (remove-advice 'add-one 'default-to-zero) Removing (:ADVICE ADD-ONE DEFAULT-TO-ZERO)
;; Now install more advice to add 1 to the result. Put it outside ;; the advice that does the doubling. > (defadvice (add-one add-one-to-result (:outside double-result)) (x) (+ 1 (advice-continue x))) #<Advice ADD-ONE ADD-ONE-TO-RESULT)B7732F> > (add-one 2) ; ((2+1)*2)+1 = 7 7
;; Replace that advice with the same piece of advice but put it ;; inside the doubling advice instead. > (defadvice (add-one add-one-to-result (:inside double-result)) (x) (+ 1 (advice-continue x))) #<ADVICE ADD-ONE-TO-RESULT B7ED9F>
> (add-one 2) ; ((2+1)+1)*2 = 8 8
;; Redefine the basic function inside the advice to return its ;; argument unchanged. > (defun add-one (x) x) ;;; Warning: Redefining ADD-ONE, keeping advice DOUBLE-RESULT, ;;; ADD-ONE-TO-RESULT ADD-ONE
> (add-one 2) ; (2+1)*2 = 6 6
;; Remove all the advice from the function. > (remove-advice 'add-one) Removing 2 pieces of advice from ADD-ONE NIL
> (add-one 1) 1
Generated with Harlequin WebMaker