[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: generic dispatch doesn't work always
- To: matti_karjalainen@hut.fi
- Subject: Re: generic dispatch doesn't work always
- From: bill@cambridge.apple.com
- Date: Thu, 23 Jan 1992 12:07:17 -0500
- Cc: info-mcl
>I am programming no-applicable method to forward calls that cannot be
>handled by some objects. I am in trouble, however, since the generic
>dispatch doesn't work in the following case:
>
>(defclass z-class () ())
>(defmethod z-method ((self integer) &key x-key)
> x-key)
>(setq z (make-instance 'z-class))
>(z-method z :my-key 'foo)
>
>> Error: Bad keyword :MY-KEY to #<Compiled Generic-function Z-METHOD
>#x36BF7E>.
>> arglist: (#<Z-CLASS #x36D281> :MY-KEY FOO)
>> Allowable keys: #()
>> While executing: CCL::%CHECK-KEYWORDS-BAD-KEY
>> Type Command-. to abort.
>
>Instead of error "Bad keyword" it should call no-applicable-method. Because
>it traps to an error before that I can't do anything. It happens if there
>are keyword options in the call. I checked the same case on Symbolics where
>it works as it should.
>
>Matti Karjalainen
>Helsinki University of Technology
I believe MCL follows the letter of the law in this regard while Symbolics
does not. CLtL2 p. 793 says, "If a generic function is passed a keyword
argument that no applicable method accepts, an error is signaled." I can,
however, understand that it is more useful to call no-applicable-method
than to signal the bad keyword error. The fix is easy. Here's a patch
(included as source as there are a number of versions out there with
incompatible FASL formats):
--------------------------------------------------------------
; bad-keyword-patch.lisp
;
; call NO-APPLICABLE-METHOD instead of signalling a bad keyword error for
; the following code:
#|
(defclass z-class () ())
(defmethod z-method ((self integer) &key x-key)
x-key)
(setq z (make-instance 'z-class))
(z-method z :my-key 'foo)
|#
(in-package :ccl)
(let ((*warn-if-redefine* nil)
(*warn-if-redefine-kernel* nil))
(defun make-standard-combined-method (methods cpls gf)
(unless (null cpls)
(setq methods (sort-methods
methods cpls (%gf-precedence-list (combined-method-gf gf)))))
(let* ((keywords (compute-allowable-keywords-vector gf methods))
(combined-method (make-standard-combined-method-internal
methods gf keywords)))
(if (and keywords methods)
(make-keyword-checking-combined-method gf combined-method keywords)
combined-method)))
)