Pergunta

This code works as I want, except for the warning message. In GNU Common Lisp, how do I suppress that message without suppressing other possible warning messages?

 1 (defgeneric zang (x y)
 2   (:documentation "they want you to put documentation here"))
 3 (defmethod zang ((a number) (b string))
 4   (format t "got to zang ((~s number) (~s string))~%" a b))
 5 (defmethod zang ((a integer) (b string))
 6   (format t "got to zang ((~s integer) (~s string))~%" a b)
 7   (when (evenp a)
 8     (format t "passing control to the other guy~%")
 9     (call-next-method (1+ a) "hoo boy")
10     (format t "returned control from the other guy~%")))
11 (defmethod no-applicable-method (zang &rest args)
12   (format t "no applicable method for (zang ~{~s~^ ~})~%" args))
13 (zang 3.5 "hi")
14 (zang 3 "hi")
15 (zang 4 "hi")
16 (zang "hello" "world")
WARNING: Replacing method #<STANDARD-METHOD (#<BUILT-IN-CLASS T>)> in
         #<STANDARD-GENERIC-FUNCTION NO-APPLICABLE-METHOD>
got to zang ((3.5 number) ("hi" string))
got to zang ((3 integer) ("hi" string))
got to zang ((4 integer) ("hi" string))
passing control to the other guy
got to zang ((5 number) ("hoo boy" string))
returned control from the other guy
no applicable method for (zang "hello" "world")

EDIT in response to Vatine's kind reply:

I tried that, and the situation escalated from a warning to a fatal error:

 (defgeneric zang (x y)
   (:documentation "they want you to put documentation here"))
 (defmethod zang ((a number) (b string))
   (format t "got to zang ((~s number) (~s string))~%" a b))
 (defmethod zang ((a integer) (b string))
   (format t "got to zang ((~s integer) (~s string))~%" a b)
   (when (evenp a)
     (format t "passing control to the next guy~%")
     (call-next-method (1+ a) "hoo boy")
     (format t "returned control from the next guy~%")))
 ;(defmethod no-applicable-method (zang &rest args)
 ;  (format t "no applicable method for (zang ~{~s~^ ~})~%" args))
 (defmethod no-applicable-method ((zang eql #'zang) &rest args)
   (format t "no applicable method for (zang ~{~s~^ ~})~%" args))
 (zang 3.5 "hi")
 (zang 3 "hi")
 (zang 4 "hi")
 (zang "hello" "world")
*** - DEFMETHOD NO-APPLICABLE-METHOD: Invalid specialized parameter in method
      lambda list ((ZANG EQL #'ZANG) &REST ARGS): (ZANG EQL #'ZANG)
Foi útil?

Solução

You need to provide a correct argument list for NO-APPLICABLE-METHOD. If you use a compiler (even the CLISP implementation can compile via COMPILE-FILE), you also should get an error message at compile time about the incorrect argument list.

The LispWorks compiler for example says:

**++++ Error between functions:
 An argument is not an atom or list of two elements : (ZANG EQL (FUNCTION ZANG))

Fixed version:

(defgeneric zang (x y)
   (:documentation "they want you to put documentation here"))
(defmethod zang ((a number) (b string))
   (format t "got to zang ((~s number) (~s string))~%" a b))
(defmethod zang ((a integer) (b string))
   (format t "got to zang ((~s integer) (~s string))~%" a b)
   (when (evenp a)
     (format t "passing control to the next guy~%")
     (call-next-method (1+ a) "hoo boy")
     (format t "returned control from the next guy~%")))
;(defmethod no-applicable-method (zang &rest args)
;  (format t "no applicable method for (zang ~{~s~^ ~})~%" args))

(defmethod no-applicable-method ((zang (eql #'zang)) &rest args)
   (format t "no applicable method for (zang ~{~s~^ ~})~%" args))

Example:

(defun test ()
 (zang 3.5 "hi")
 (zang 3 "hi")
 (zang 4 "hi")
 (zang "hello" "world"))

CL-USER 1 > (test)
got to zang ((3.5 number) ("hi" string))
got to zang ((3 integer) ("hi" string))
got to zang ((4 integer) ("hi" string))
passing control to the next guy
got to zang ((5 number) ("hoo boy" string))
returned control from the next guy
no applicable method for (zang "hello" "world")
NIL

Outras dicas

I think you want to define a method on no-applicable-method as:

(defmethod no-applicable-method ((zang (eql #'zang)) &rest args)
   ...)

As-is, you're declaring a method that applies to all generic functions and that's why clisp is telling you that you're replacing an already-defined method.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top