[cells-devel] make-instance, initarg, c-in
Ramarren
ramarren at gmail.com
Wed Jul 1 05:53:52 UTC 2009
Hello,
Not that I think this is a really good idea, but you can do it using
the infamous MOP, using http://www.cliki.net/closer-mop as a
compatibility layer:
(defmodel auto-cin-model ()
())
(defun class-initargs (class)
(let ((slots (closer-mop:class-slots class)))
(let ((class-initargs
(mapcar #'closer-mop:slot-definition-initargs slots)))
(remove-if #'(lambda (x)
(= (length x) 1))
(mapcar #'list* slots class-initargs)))))
(defmethod shared-initialize :after ((instance auto-cin-model)
slot-names &rest initargs)
(declare (ignore slot-names))
(let ((class-initargs (class-initargs (class-of instance)))
(leftmost-initargs (make-hash-table)))
(loop for (init-arg init-value) on initargs by #'cddr
for init-slot = (car (rassoc init-arg class-initargs :test #'member))
for slot-name = (closer-mop:slot-definition-name init-slot)
do (when (and (not (gethash init-slot leftmost-initargs))
(cells::md-slot-cell-type (class-name
(class-of instance)) slot-name)
(not (typep init-value 'cell)))
(setf (slot-value instance slot-name) (c-in init-value)))
(setf (gethash init-slot leftmost-initargs) t))))
Now all models inheriting from auto-cin-model will have this
behaviour. This is only marginally tested, so probably contains bugs.
For one thing, it overrides cells-created shared-initialize, but that
is only for checking for error which is impossible in this situation
anyway.
Regards,
Jakub Higersberger
On Tue, Jun 30, 2009 at 11:32 PM, Bastian Müller<turbo24prg at web.de> wrote:
> Hi,
>
> I'm currently using cells and it works very well,
> except one thing seems a little unhandy:
>
> When defining a model it's possible to use (c-in ..)
> as an initform to define a slot as a cell, but when
> instantiating a class you have to supply (c-in ...)
> instead the normal value, eg.
>
> (defmodel x ()
> ((y :accessor y
> :initarg :y
> :initform (c-in nil))
> ...))
>
> (let ((test (make-instance 'x :y (c-in 1))))
> (setf (y test) 2))
>
> works, but instead sth like
>
> (let ((test (make-instance 'x :y 1)))
> (setf (y test) 2))
>
> would be nice.
>
> I tried it with
>
> (defmethod initialize-instance ((self x) &rest rest)
> (loop for slot in rest by #'cddr
> do (let ((value (getf rest slot))
> (name (intern (symbol-name slot))))
> (setf (slot-value self name)
> (c-in value)))))
>
> but I just get:
>
> The slot CELLS::.CELLS is unbound in the object #<X {10032D5FC1}>.
> [Condition of type UNBOUND-SLOT]
>
> Is there any way to get this behavior?
>
> kind regards,
> Bastian
>
> _______________________________________________
> cells-devel site list
> cells-devel at common-lisp.net
> http://common-lisp.net/mailman/listinfo/cells-devel
>
More information about the cells-devel
mailing list