[Openmcl-devel] REMOVE-ALL-DIRECT-METHODS
Alexander Repenning
ralex at cs.colorado.edu
Wed Aug 3 19:14:07 PDT 2011
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/0262610744>
>
>
>> 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20110803/b4bf9fe5/attachment.htm>
More information about the Openmcl-devel
mailing list