[Openmcl-devel] REMOVE-ALL-DIRECT-METHODS

Gary Byers gb at clozure.com
Wed Aug 3 22:41:07 PDT 2011


Or (for those who are paying a bit more attention than I was and actually
read/remember the documentation they cite ...)

Sorry for misremembering how REMOVE-METHOD works and for not
bothering to check.  It's a bit easier to determine what GF (if any)
a method is associated with than you're making it:


(defun remove-all-direct-methods (class)
   (dolist (method (copy-list (specializer-direct-methods class)))
     (let* ((gf (method-generic-function method)))
       (when gf (remove-method gf method)))))





On Wed, 3 Aug 2011, Alexander Repenning wrote:

> 
> On Aug 3, 2011, at 4:05 PM, Gary Byers wrote:
> 
> 
>
>       On Wed, 3 Aug 2011, Alexander Repenning wrote:
>
>             I need to remove all direct methods of a class.
> 
>
>       I assume that you mean that you need to remove these methods
>       from the
>       generic functions that they're associated with. ?If so, you want
>       to
>       use REMOVE-METHOD, which both breaks that association between gf
>       and
>       method and removes the method from the
>       SPECIALIZER-DIRECT-METHODS ?lists
>       of all of the method's specializers:
>
>       (defun remove-all-direct-methods (class)
>       ?(dolist (method (SPECIALIZER-DIRECT-METHODS class))
>       ???(REMOVE-METHOD method)))
> 
> 
> 
> 
> Thanks Gary. I had to add some code to find the gf. I am sure this could
> have been done more elegantly. I have been poking
> around?http://www.lisp.org/mop/index.html I am glad it is online but it can
> be a bit confusing.
> 
> Anyway, this does that I need it to do:
> 
> (defun REMOVE-ALL-DIRECT-METHODS (class)
> ? (dolist (Generic-Function (ccl::specializer-direct-generic-functions
> class))
> ? ? (dolist (Method (copy-list (ccl::generic-function-methods
> Generic-Function)))
> ? ? ? (when (member Method (ccl::specializer-direct-methods class))
> ? ? ? ? ;; (format t "~%removing method ~A from generic function ~A" Method
> Generic-Function)
> ? ? ? ? (remove-method Generic-Function Method)))))
> 
> 
> 
> ;; test case
> 
> (defclass animal ()
> ? ())
> 
> (defmethod make-sound ((self animal)) 'generic-sound)
> 
> (defclass dog (animal)
> ? ())
> 
> (defmethod make-sound ((self dog)) 'wuff)
> 
> 
> 
> (make-sound (make-instance 'dog))
> 
> (remove-all-direct-methods (find-class 'dog))
> 
> (make-sound (make-instance 'dog))
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
>
>       REMOVE-METHOD will call REMOVE-DIRECT-METHOD on the method and
>       each of its
>       specializers, which means that it can destructively modify the
>       list that
>       the DOLIST above is traversing. ?That modification -probably-
>       means
>       "sets the list to its CDR", but if you're at all paranoid about
>       that you
>       could do:
>
>       ... (dolist (method (copy-list (SPECIALIZER-DIRECT-METHODS
>       class)))) ...
>
>       The functions whose names are capitalized above are part of the
>       MOP (and
>       those names are exported from the "CCL" and "OPENMCL-MOP"
>       packages in CCL);
>       their behavior is described in
>
>       <http://www.lisp.org/mop/index.html>
>
>       which is essentially the same material that's available as
>       chapters 5 and 6
>       of the book "The Art of the Metaobject Protocol", which is still
>       in print:
> 
> <http://www.amazon.com/Art-Metabobject-Protocol-Gregor-Kiczales/dp/02626107
>       44>
> 
>
>             The following code appears to remove all the direct
>             methods yet they can still be invoked. Perhaps there
>             is some caching going on? This is an evil CCL hack.
>             Is this a caching problem? Is there a better,
>             perhaps MOP based approach?
> 
> 
>
>             (defun REMOVE-ALL-DIRECT-METHODS (Class)
>
>             (dolist (method (slot-value Class
>             'ccl::direct-methods))
>
>             ?(ccl::%remove-direct-methods method)))
> 
> 
> 
>
>             ;; example
>
>             (remove-all-direct-methods (find-class
>             'player_a_agent))
> 
>
>             ;; but direct player_a_agent method still executes.
> 
> 
>
>             thanks,
>
>             Alex
>
>             _______________________________________________
>
>             Openmcl-devel mailing list
>
>             Openmcl-devel at clozure.com
>
>             http://clozure.com/mailman/listinfo/openmcl-devel
> 
> 
> 
> 
> Prof. Alexander Repenning
> 
> 
> University of Colorado
> 
> Computer Science Department
> 
> Boulder, CO 80309-430
> 
> 
> vCard: http://www.cs.colorado.edu/~ralex/AlexanderRepenning.vcf
> 
> 
> 
> 
>



More information about the Openmcl-devel mailing list