Prev: translating cmucl command line to sbcl
Next: LOAD-TIME-VALUE [was: Re:... [Re: DEFSTRUCT and lexical environment]]
From: Rui Maciel on 25 Oct 2009 06:04 Let's say we have a set of lists. Is there a way to trigger specific actions by not only operating on those lists (i.e., push'ing and pop'ing) but also tweaking it's values? Thanks in advance, Rui Maciel
From: Pascal J. Bourguignon on 25 Oct 2009 06:05 Rui Maciel <rui.maciel(a)gmail.com> writes: > Let's say we have a set of lists. Is there a way to trigger specific > actions by not only operating on those lists (i.e., push'ing and > pop'ing) but also tweaking it's values? (let ((fruits (list 'apple 'orange 'cranberry))) (setf (third fruits) 'banana) fruits) (let ((fruits (list 'apple 'orange 'cranberry))) (setf (nth 2 fruits) 'banana) fruits) But be careful that these lists are all built only from mutable parts (ie. use LIST, not QUOTE), if you want to mutate them like this. -- __Pascal Bourguignon__
From: Alex Mizrahi on 25 Oct 2009 08:08 RM> Let's say we have a set of lists. Is there a way to trigger specific RM> actions by not only operating on those lists (i.e., push'ing and RM> pop'ing) but also tweaking it's values? "Trigger action" as in observer pattern? No, it is possible only with classes.
From: Rui Maciel on 25 Oct 2009 10:07 Alex Mizrahi wrote: > "Trigger action" as in observer pattern? No, it is possible only > with classes. Could you please provide an example? Thanks in advance, Rui Maciel
From: Alex Mizrahi on 25 Oct 2009 12:16
??>> "Trigger action" as in observer pattern? No, it is possible only ??>> with classes. RM> Could you please provide an example? I'm not sure I undertstand your question correctly. Do you want to recieve some sort of notification when something changes list entries? It is possible to do this by re-implementing lists in CLOS. Here's example how one can implement observable conses and some list API on top of them: http://paste.lisp.org/display/89244 Then it will sort of work: CL-USER> (in-package :obs-test) #<PACKAGE "OBS-TEST"> OBS-TEST> (setf *observer* (make-instance 'logging-observer)) #<LOGGING-OBSERVER {B3A4D01}> OBS-TEST> (defparameter *list* (list 1 2 3 4)) *LIST* OBS-TEST> *list* #<1 . #<2 . #<3 . #<4 . NIL>>>> OBS-TEST> (second *list*) 2 OBS-TEST> (setf (second *list*) 'b) `CAR` of `#<2 . #<3 . #<4 . NIL>>>` is going to change from `2` to `B` B OBS-TEST> *list* #<1 . #<B . #<3 . #<4 . NIL>>>> But it won't work for more complex cases, won't work with PUSH/POP (unless you invent some trick), and I doubt it has any practical value. But I hope you've got an idea -- if you want to track writes to some slots via accessors, implement (setf accessorname) :before or :after method. This won't work with (setf (slot-name ....)) though, if you want it to work then you probably need to deal with metaclasses or something like that. Also there are few libs which can help with observers and stuff. Cells among them. |