Method combination
All :before methods are run before the primary method. CLOS looks for :before methods in the same order as it looks for primary methods: instance first, then class, then direct superclasses. This order is called most specific first. After all applicable :before methods have run, Macintosh Common Lisp calls the primary method, then the:after methods in reverse order, from the :after methods associated with t all the way down to the class and instance :after methods if there are any. (This order is called least specific first.)
All :around methods (which are seldom used) specify code that is to be called instead of other applicable methods, but can pass control to other methods, including the primary, :before, and :after methods. The effect is that the :around method runs "around" the other methods. An :around method uses call-next-method to pass control to the other methods.
Here is an example of :before and :after methods.
? (defmethod say :before ((child bored-kid) sentence)
(declare (ignore sentence))
(princ "First there is a :before method from bored-kid.")
(terpri))
#<Method SAY :BEFORE (BORED-KID T)>
? (defmethod say :after ((child bored-kid) sentence)
(declare (ignore sentence))
(princ "Then there is an :after method from bored-kid.")
(terpri))
#<Method SAY :AFTER (BORED-KID T)>
? (defmethod say :around ((child bored-kid) sentence)
(declare (ignore sentence))
(princ "This illustrates method combination.")
(terpri)
(call-next-method))
#<Method SAY :AFTER (BORED-KID T)>
? (say bad-max "I hate homework.")
This illustrates method combination.
First there is a :before method from bored-kid.
This primary method comes from happy-kid.
Then there is an :after method from bored-kid.
NIL
When say is called on the instance bad-max, CLOS looks first for :around methods. Then it searches for :before methods, starting with the most specific, and finds and runs a :before method associated with bored-kid. It runs the applicable primary method, which is associated with happy-kid. Then it looks for :after methods, starting with the least specific, and finds the one associated with bored-kid, which it runs.
There can be multiple :before and :after methods, as in the following example:
? (defmethod say :after ((child fourth-grader) sentence)
(declare (ignore sentence))
(format t "This is an :after method for fourth-grader."))
#<Method SAY :AFTER (FOURTH-GRADER T)>
? (defmethod say :after ((child happy-kid) sentence)
(declare (ignore sentence))
(princ "Everybody likes my ~A. \(This is an :after method for
happy-kid\)" (pet child))
(terpri))
#<Method SAY :AFTER (HAPPY-KID T)>
? (setq yoichi (make-instance 'bored-kid-with-pet
:pet "dog Lizzie"))
#<BORED-KID-WITH-PET #x554FA9>
? (say yoichi "Nobody ever listens to me.")
This illustrates method combination.
First there is a :before method from bored-kid.
This primary method comes from happy-kid.
This is an :after method for fourth-grader.
Everybody likes my dog Lizzie. (This is an :after method for happy-kid)
Then there is an :after method from bored-kid.
NILCombining all methods applicable to this instance produces the effective method, the complete list of primary and secondary methods.
Generated with Harlequin WebMaker