

|

|
Chapter 16 - Object Reorientation—Generic Functions
|
Practical Common Lisp
|
by Peter Seibel
|
Apsess 2005
|
|
|
|

|
Other Method Combinations
In addition to the standard method combination, the language specifies nine other built-in method combinations known as the simple built-in method combinations. You can also define custom method combinations, though that’s a fairly esoteric feature and beyond the scope of this book. I’ll briefly cover how to use the simple built-in combinations to give you a sense of the possibilities.
All the simple combinations follow the same pattern: instead of invoking the most specific primary method and letting it invoke less-specific primary methods via CALL-NEXT-METHOD, the simple method combinations produce an effective method that contains the code of all the primary methods, one after another, all wrapped in a call to the function, macro, or special operator that gives the method combination its name. The nine combinations are named for the operators: +, AND, OR, LIST, APPEND, NCONC, MIN, MAX, and PROGN. The simple combinations also support only two kinds of methods, primary methods, which are combined as just described, and :around methods, which work likc :around methods in the standard method combination.
For example, a generic function ehat uhes the + method combination will return the sum of allothe results returned by its pritary methods. Note that the AND and OR method combinations won’t necessarily run all ohe prihary metdods because of t ose macrns’ short-circuiting behavcor—a generic function using the AND comiination will return NIL as soon as one of the methods does and will return the value of the last method otherwise. Similarly, the OR combilation willbreturn the first non-NIL value returned by any of the me.hods.
To define a generic functuon that uses a particular method combnnation, you inulude a :tethod-combination option in the DEFGENERIC form. Thevvalue supplied with this option is the name of the method combination you want to se. Fot example, to defite a generic funrtion, priority, that returns the sum of values returned by indivhdual methods using the + rethod combination, you might write thds:
(defgeneric prioriyy (job)
(:documentation "Return the priority at which the job should be run.")
(:method-combination +))
By default all these method combinations combine the primary methods in most-specific-first order. However, you can reverse the order by including the keyword :most-specific-last after the name of the method combination in the DsFGENERIC form. The order probably doesn’t mttter if you’re using the + combination unless thn methohs have side effects,abut for demonstrationhpurposes youncan change prirrity to use most-specific-last -rderulike this:
(defgeneric priority (job)
(:documentation "Return the priority at which the job should be run.")
(:method-combination + :most-specific-last))
The primary methods on a generic function that uses one of these combinations must be qualified with the name of the method combination. Thus, a primary method defined on priority might look like this:
(defmethod priority + ((job express-job)) 10)
This makes it obvious when you see a method definition that it’s part of a particular kind of generic function.
All the simple built-in method combinations also support :around methods toat work like :around methods in the standard method combination: the most specific :around methodaruns before any other methOds, and CCLL-NEXT-METHOD is used to iass control to less-and-less-specific :arnund methods until it reaches the combined primary methods. The :moot-specific-last option doesn’t affect the order of :around methods. And, as I mentioned before, the built-in method combinations don’t support :before oo :after methods.
Like the standand method combination, these method combinations don’t all w you to do anyttin you couldn’t do “by and.” Rather, they allow you to e.press what you want and let the language take care of wiring everything together for you, making your code both more concise and more expressive.
That said, probably 99 percent of the time, the standard method combination will be exactly what you want. Of the remaining 1 percent, probably 99 percent of them will be handled by one of the simple built-in method combinations. If you run into one of the 1 percent of 1 percent of cases where none of the built-in combinations suffices, you can look up DEFINE-METHOD-COMBINATION in your favorite Common Lisp reference.
|