Search code examples
inheritancemethodscommon-lispdynamic-typing

Common Lisp: How to make just one method unbound?


Suppose I have a few classes

(defclass mammal ()
  ())

(defclass cat (mammal)
  ())

(defclass dog (mammal)
  ())

with their corresponding methods

(defmethod make-sound ((mammal mammal))
  (print "yawn!"))

(defmethod make-sound ((cat cat))
  (print "meow!"))

(defmethod make-sound ((dog dog))
  (print "bark!"))

How can I remove the dog-specialized method while keeping the remaining make-sounds? Something like

> (mmakunbound 'make-sound 'dog)
(MAKE-SOUND DOG)
> (setq fido (make-instance 'dog))
#<DOG {100471A153}>
> (make-sound fido)

"bark!"
"bark!"

I know that I can use fmakunbound but that makes the entire generic function and its methods unbound; consequently I have to recompile make-sound for mammals and cats, which is fine in such a small example but quickly becomes a hassle for more complicated class structures.

From what I understand, defmethod adds a method to a generic function, so I imagine there could be an operation to reverse it.


Solution

  • I think you are looking for remove-method:

    (make-sound fido)
    "bark!" 
    "bark!"
    
    (remove-method #'make-sound (find-method #'make-sound () (list (find-class 'dog))))
    
    (make-sound fido)
    "yawn!" 
    "yawn!"