Re: Auto-creation in a SETF method
Peter Seibel <[email protected]> 23 Feb 2004 12:25:34 -0800
| Newsgroups | gmane.lisp.clump |
|---|---|
| Message-ID | <[email protected]> |
JP Massar <[email protected]> writes: > Suppose I've defined an class called ZOOP, and it has a slot SLOT. > > > Now suppose, for whatever perverted reason, I want the following: > > (let ((x nil)) > (setf (ZOOP-SLOT x) 23)) > > to 'just work', that is, if X is not a ZOOP, I want to effectively have the > SETF generate > > (SETQ X (MAKE-INSTANCE :ZOOP)) > > and then do the 'real' SETF using a setf function or whatever. > > So > > (progn > (when (not (typep x 'zoop)) (setq x (make-instance :zoop))) > (setf-zoop-slot x 23)) > > (For simplicity, for the moment, let's say I only want it to work when > X is a symbol, not an arbitrary place. And let's ignore completely what > might or might not be the semantics when X is not a place) > > After some perusal of DEFINE-SETF-EXPANDER, DEFSETF and whatnot, > I am convincing myself that this is simply not possible. Unless I misunderstand your requirements here is--I think--an existance proof that it *is* possible. This also handles X being an arbitrary place and gives a semi-meaningful error message if X is not a place: (defclass zoop () ((slot :initarg :slot :reader zoop-slot))) (define-setf-expander zoop-slot (x &environment env) (multiple-value-bind (xtemps xvals xstore-vars xwriter xreader) (get-setf-expansion x env) (let ((store (gensym)) (xstore (first xstore-vars))) (if (rest xstore-vars) (error "To many store vars.")) (values nil nil (list store) `(let* (,@(mapcar #'list xtemps xvals) (,xstore (if (typep ,xreader 'zoop) ,xreader (make-instance 'zoop)))) (setf (slot-value ,xstore 'slot) ,store) ,xwriter ,store) `(slot-value ,xreader 'slot))))) -Peter -- Peter Seibel [email protected] Lisp is the red pill. -- John Fraser, comp.lang.lisp