[Next] [Previous] [Up] [Top] [Contents] [Index]

Method combination

Creating auxiliary methods and using method qualifiers

Only one primary method can be applied to any set of arguments, but its behavior can be modified using auxiliary methods.

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.
NIL

Combining all methods applicable to this instance produces the effective method, the complete list of primary and secondary methods.

Mixin classes and auxiliary methods

Gettmg Started with MCL - 19 OCT 1996
[Next] [Previous] [Up] [Top] [Contents] [Index]

Generated with Harlequin WebMaker