Bruno Haible | 2 Aug 2004 13:15

standard method-combination ignores overridden compute-applicable-methods

Standard method-combination appears to ignore an overridden
compute-applicable-methods function, if one of the methods is an :AROUND
method. SBCL 0.8.11. Here are two test cases:

;; Check that it's possible to change the order of applicable methods from
;; most-specific-first to most-specific-last.
(progn
  (defclass msl-generic-function (standard-generic-function)
    ()
    (:metaclass sb-pcl:funcallable-standard-class))
  (defun reverse-method-list (methods)
    (let ((result '()))
      (dolist (method methods)
        (if (and (consp result)
                 (equal (method-qualifiers method) (method-qualifiers (caar result))))
          (push method (car result))
          (push (list method) result)))
      (reduce #'append result)))
  (defmethod sb-pcl:compute-applicable-methods ((gf msl-generic-function) arguments)
    (reverse-method-list (call-next-method)))
  (defmethod sb-pcl:compute-applicable-methods-using-classes ((gf msl-generic-function) classes)
    (reverse-method-list (call-next-method)))
  (defgeneric testgf07 (x) (:generic-function-class msl-generic-function)
    (:method ((x integer)) (cons 'integer (if (next-method-p) (call-next-method))))
    (:method ((x real)) (cons 'real (if (next-method-p) (call-next-method))))
    (:method ((x number)) (cons 'number (if (next-method-p) (call-next-method))))
    (:method :around ((x integer)) (coerce (call-next-method) 'vector)))
  (list (testgf07 5.0) (testgf07 17)))
Expected: ((number real) #(number real integer))
Got:      ((number real) #(integer real number))

;; Check that it's possible to filter-out applicable methods.
(progn
  (defclass nonumber-generic-function (standard-generic-function)
    ()
    (:metaclass sb-pcl:funcallable-standard-class))
  (defun nonumber-method-list (methods)
    (remove-if #'(lambda (method)
                   (member (find-class 'number) (sb-pcl:method-specializers method)))
               methods))
  (defmethod sb-pcl:compute-applicable-methods ((gf nonumber-generic-function) arguments)
    (nonumber-method-list (call-next-method)))
  (defmethod sb-pcl:compute-applicable-methods-using-classes ((gf nonumber-generic-function) classes)
    (nonumber-method-list (call-next-method)))
  (defgeneric testgf08 (x) (:generic-function-class nonumber-generic-function)
    (:method ((x integer)) (cons 'integer (if (next-method-p) (call-next-method))))
    (:method ((x real)) (cons 'real (if (next-method-p) (call-next-method))))
    (:method ((x number)) (cons 'number (if (next-method-p) (call-next-method))))
    (:method :around ((x integer)) (coerce (call-next-method) 'vector)))
  (list (testgf08 5.0) (testgf08 17)))
Expected: ((real) #(integer real))
Got:      ((real) #(integer real number))

Bruno

-------------------------------------------------------
This SF.Net email is sponsored by OSTG. Have you noticed the changes on
Linux.com, ITManagersJournal and NewsForge in the past few weeks? Now,
one more big change to announce. We are now OSTG- Open Source Technology
Group. Come see the changes on the new OSTG site. www.ostg.com

Gmane