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


> At  1:22 PM 12/11/93 -0700, Markus Stolze wrote:
> >I was trying to get inbetween write-updates of *all* slots of a class.
> >
> >The strait forward way seemed to be specialize the
> >(setf slot-value-using-class) method, but as it turnes out, this part of the
> >MOP is not supported in MCL. (setf Slot-Value) accesses slots without
> >calling (setf slot-value-using-class).
> >
> >The next way I thought of was to specialize the initialize-instance method
> >of the meta-class Writer-Method and modify the method-code at definition
> >time. But I had to find out that -while the meta-class Writer-Method
> >exisits- method-definition in MCL bypasses this and instances of this class
> >are never made.
> >
> >So, the question remains: Are there ways (one would be enough) in MCL to
> >get inbetween write-updates of *all* slots of a class?
> I wrote a quick and dirty slot-value-using-class for MCL. It's drawback
> is that it makes all SLOT-VALUE calls, even the implicit ones in
> DEFCLASS generated accessor methods, go through SLOT-VALUE-USING-CLASS
> (a real implementation would mark the class wrapper somehow to let
> SLOT-VALUE know when calling SLOT-VALUE-USING-CLASS is not necessary.
> The patch is available for anonymous FTP from cambridge.apple.com in
> the file "/pub/mcl2/contrib/slot-value-using-class.lisp"

Here are some other ideas--none perfect, however.
If you can live with access strictly through the writer functions
which are automatically generated by using :accessor and :writer in
your DEFCLASS, it's pretty easy to override them, or even better,
create :around, :before, and :after methods for them. But of course
you have to do this manually for each slot. (Hint: the standard
writer methods are 2-way multimethods on ((value t) (instance your-class))
in that order.)
The above works only when you change a slot value--it won't work
when initializing the slots with initargs in the make-instance call.
To do that, you must also override shared-initialize for your class.

Another, somewhat more radical, approach is to simply define no
:accessor or :writer functions in the defclass at all, and write some
kind of universal slot-writer method for your class. This method
could take arguments of ((self your-class) slotname value) and it
would call slot-value as necessary to write the slots. It could
do a lookup at runtime to see if slotname was valid, so you wouldn't
have to change it when you add or remove a slot. This method could
take care of whatever side-effects you need.

Of course, none of the above works if you insist on using the slot-value
function from your outside code, which you shouldn't be doing anyway, if
you're being philosophically pure. (declare (ignore preaching :-))

If you MUST override slot-value, the slot-value-using-class patch is
probably your best bet.