[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How can one get a method object?

    Date: Wed, 03 May 89 11:58:55 PDT
    From: Darrell <shane%blackcomb@rand.org>

    First, can I use add-method and remove-method to add a method 
    temporarily?  If yes then how can I get a method object to pass 
    to add-method & remove-method?  Defmethod returns nil and find-method 
    does not seem to be implemented in the "no cute version" pcl.  

FIND-METHOD is called GET-METHOD in no cute name PCL.

Here is some code which may be illustrative for you.  Note that you will
have to change this code somewhat in a future release, but the basic
idea will be the same:

(in-package 'pcl)

;;; Define a one argument method on the generic function GF.  The method
;;; has the specializer SPECIALIZER and simply returns the value VALUE.
(defun specialize-to-class (gf specializer value)
  (let ((method (make-instance 'standard-method
			       :qualifiers ()
			       :type-specifiers (list specializer)
			       :arglist '(arg)
			       :function #'(lambda (arg) value))))
    (add-method gf method)))

(defvar *my-generic-function* (make-instance 'standard-generic-function))

(specialize-to-class *my-generic-function* (find-class 'symbol) "Symbol")
(specialize-to-class *my-generic-function* (find-class 'number) "Number")
(specialize-to-class *my-generic-function* (find-class 'class)  "Class")
(specialize-to-class *my-generic-function* (find-class 't)      "Other")

(funcall *my-generic-function* 'foo)             ==> "Symbol"
(funcall *my-generic-function* '1)               ==> "Number"
(funcall *my-generic-function* (find-class 't))  ==> "Class"
(funcall *my-generic-function* '(1 2 3))         ==> "Other"

You should also note that REMOVE-METHOD can be used to remove a method
from a generic function.  The generic function GENERIC-FUNCTION-METHODS
can be used to to get a list of all the methods on a generic function.
So, for example, if you do a defmethod like:

(defmethod foo ((p position)) ..)

and you want to get rid of it (imagine undefmethod didn't exist).  You
could say:

(let ((method (get-method #'foo () (list (find-class 'position)))))
  (remove-method #'foo method))