1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
<HTML>
<HEAD>
<TITLE>Brief Guide to CLOS: Method combination.</TITLE>
</HEAD>
<BODY>
<A HREF="CLOS-guide-6.html"><IMG SRC="prev.gif" ALT="Previous"></A>
<A HREF="CLOS-guide-8.html"><IMG SRC="next.gif" ALT="Next"></A>
<A HREF="CLOS-guide.html#toc7"><IMG SRC="toc.gif" ALT="Contents"></A>
<HR>
<H2><A NAME="s7">7. Method combination.</A></H2>
<P>When more than one class defines a method for a generic function, and
more than one method is applicable to a given set of arguments, the
applicable methods are combined into a single "effective method".
Each individual method definition is then only part of the definition
of the effective method.</P>
<P>One kind of method combination is always supported by <CODE>CLOS</CODE>. It is
called standard method combination. It is also possible to define
new kinds of method combination. Standard method combination
involves four kinds of methods:</P>
<P>
<UL>
<LI>Primary methods form the main body of the effective method.
Only the most specific primary method is called, but it can
call the next most specific primary method by calling
<BLOCKQUOTE><CODE>
<PRE>
(call-next-method)
</PRE>
</CODE></BLOCKQUOTE>
</LI>
<LI> <CODE>:BEFORE</CODE> methods are all called before the primary method, with
the most specific <CODE>:BEFORE</CODE> method called first.
</LI>
<LI> <CODE>:AFTER</CODE> methods are all called after the primary method, with
the most specific <CODE>:AFTER</CODE> method called last.
</LI>
<LI> <CODE>:AROUND</CODE> methods run before the other methods. As with
primary methods, only the most specific is called and the
rest can be invoked by <CODE>CALL-NEXT-METHOD</CODE>. When the least
specific <CODE>:AROUND</CODE> method calls <CODE>CALL-NEXT-METHOD</CODE>, what it
calls is the combination of <CODE>:BEFORE</CODE>, <CODE>:AFTER</CODE>, and primary
methods.</LI>
</UL>
</P>
<P><CODE>:BEFORE</CODE>, <CODE>:AFTER</CODE>, and <CODE>:AROUND</CODE> methods are indicated by putting the
corresponding keyword as a qualifier in the method definition.
<CODE>:BEFORE</CODE> and <CODE>:AFTER</CODE> methods are the easiest to use, and a simple
example will show how they work:</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
(defclass food () ())
(defmethod cook :before ((f food))
(print "A food is about to be cooked."))
(defmethod cook :after ((f food))
(print "A food has been cooked."))
(defclass pie (food)
((filling :accessor pie-filling :initarg :filling :initform 'apple)))
(defmethod cook ((p pie))
(print "Cooking a pie")
(setf (pie-filling p) (list 'cooked (pie-filling p))))
(defmethod cook :before ((p pie))
(print "A pie is about to be cooked."))
(defmethod cook :after ((p pie))
(print "A pie has been cooked."))
(setq pie-1 (make-instance 'pie :filling 'apple))
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>And now:</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
<cl> (cook pie-1)
"A pie is about to be cooked."
"A food is about to be cooked."
"Cooking a pie"
"A food has been cooked."
"A pie has been cooked."
(cooked apple)
</PRE>
</CODE></BLOCKQUOTE>
</P>
<HR>
<A HREF="CLOS-guide-6.html"><IMG SRC="prev.gif" ALT="Previous"></A>
<A HREF="CLOS-guide-8.html"><IMG SRC="next.gif" ALT="Next"></A>
<A HREF="CLOS-guide.html#toc7"><IMG SRC="toc.gif" ALT="Contents"></A>
</BODY>
</HTML>
|