:before :after :method-combination

:method-combination

CL-USER> (defclass foo1 nil nil)
;=> #<STANDARD-CLASS FOO1>
CL-USER> (defclass foo2 (foo1) nil)
;=> #<STANDARD-CLASS FOO2>
CL-USER> (defclass foo3 (foo2) nil)
;=> #<STANDARD-CLASS FOO3>

;; [ + and append list max min nconc or progn ] が利用可能らしい
CL-USER> (defgeneric method1 (x)
           (:method-combination append))
;=> #<STANDARD-GENERIC-FUNCTION METHOD1>

CL-USER> (defmethod method1 append ((x foo3)) (list 1 2 3))
;=> #<STANDARD-METHOD APPEND (#<STANDARD-CLASS FOO3>)>
CL-USER> (defmethod method1 append ((x foo2)) (list 4 5 6))
;=> #<STANDARD-METHOD APPEND (#<STANDARD-CLASS FOO2>)>
CL-USER> (defmethod method1 append ((x foo1)) (list 7 8 9))
;=> #<STANDARD-METHOD APPEND (#<STANDARD-CLASS FOO1>)>

CL-USER> (method1 (make-instance 'foo1))
;=> (7 8 9)
CL-USER> (method1 (make-instance 'foo3))
;=> (1 2 3 4 5 6 7 8 9)

メソッド・コンビネーションとそのまま言えばいいのかな?
On Lispだとメソッド結合となっています。
結合というとなんか関数合成を連想してしまうような。

:before, :after

(:around はまた後で)

CL-USER> (defmethod method2 ((x foo1)) (princ "sapporo"))
;=> #<STANDARD-METHOD (#<STANDARD-CLASS FOO1>)>
CL-USER> (defmethod method2 ((x foo3)) (princ "hokkaido"))
;=> #<STANDARD-METHOD (#<STANDARD-CLASS FOO3>)>

CL-USER> (defmethod method2 :before ((x foo1)) (princ "<"))
;=> #<STANDARD-METHOD :BEFORE (#<STANDARD-CLASS FOO1>)>
CL-USER> (defmethod method2 :after ((x foo1)) (princ ">"))
;=> #<STANDARD-METHOD :AFTER (#<STANDARD-CLASS FOO1>)>
CL-USER> (defmethod method2 :before ((x foo2)) (princ "["))
;=> #<STANDARD-METHOD :BEFORE (#<STANDARD-CLASS FOO2>)>
CL-USER> (defmethod method2 :after ((x foo2)) (princ "]"))
;=> #<STANDARD-METHOD :AFTER (#<STANDARD-CLASS FOO2>)>

CL-USER> (method2 (make-instance 'foo1))
;-> <sapporo>
;=> "sapporo"
CL-USER> (method2 (make-instance 'foo2))
;-> [<sapporo>]
;=> "sapporo"
CL-USER> (method2 (make-instance 'foo3))
;-> [<hokkaido>]
;=> "hokkaido"