定義したメソッドを削除するには - lisp-cookbook-ja/common-lisp GitHub Wiki

オブジェクトシステム(CLOS)

定義したメソッドの総称関数からの削除には、remove-methodを利用します。

総称関数自体を丸ごと削除する用途には、fmakunboundが利用できるでしょう。

(defclass foo () ())
(defclass bar (foo) ())

(defgeneric frob (n))
(defmethod frob ((x foo)) ;(1)
  (print :foo-primary))
(defmethod frob :before ((x foo)) ;(2)
  (print :foo-before))
(defmethod frob ((x bar)) ;(3)
  (print :bar-primary)  
  (call-next-method))
(defmethod frob :before ((x bar)) ;(4)
  (print :bar-before))
;; 実行

(frob (make-instance 'bar))
;-> :BAR-BEFORE 
;   :FOO-BEFORE 
;   :BAR-PRIMARY 
;   :FOO-PRIMARY 
;=> :FOO-PRIMARY

; (4)を削除
(remove-method #'frob (find-method #'frob '(:before) (list (find-class 'bar))))
(frob (make-instance 'bar))

;-> :FOO-BEFORE 
;   :BAR-PRIMARY 
;   :FOO-PRIMARY 
;=> :FOO-PRIMARY

; (3)を削除
(remove-method #'frob (find-method #'frob () (list (find-class 'bar))))
(frob (make-instance 'bar))

;-> :FOO-BEFORE 
;   :FOO-PRIMARY 
;=> :FOO-PRIMARY

; (2)を削除
(remove-method #'frob (find-method #'frob '(:before) (list (find-class 'foo))))
(frob (make-instance 'bar))
;-> :FOO-PRIMARY
;=> :FOO-PRIMARY

; (1)を削除
(remove-method #'frob (find-method #'frob () (list (find-class 'foo))))
(frob (make-instance 'bar))
;>>> error

見てのとおり若干面倒なところもありますので、処理系によっては、undefmethodのようにdefmethodと同じような構文で削除できるユーティリティが定義されていることもあるようです。(CMUCL/Lucid CL等)

他の例

(defgeneric 一期一会 (x))
(defmethod 一期一会 ((x foo))
  (remove-method #'一期一会 
                 (find-method #'一期一会 () (list (find-class 'foo))))
  (print "foo:初めまして、さようなら!"))

(defmethod 一期一会 ((x bar))
  (print "bar:初めまして、さようなら!")
  (remove-method #'一期一会 
                 (find-method #'一期一会 () (list (find-class 'bar))))
  (call-next-method))
;; 定義後1回目の呼び出し
(一期一会 (make-instance 'bar))
;-> "bar:初めまして、さようなら!" 
;   "foo:初めまして、さようなら!"
;=> "foo:初めまして、さようなら!"

;; 定義後2回目以降の呼び出し
(一期一会 (make-instance 'bar))
;>>> error (There is no applicable method for the generic function)