[cells-devel] make-instance, initarg, c-in
Ramarren
ramarren at gmail.com
Wed Jul 1 06:21:45 UTC 2009
I forgot that a single initarg can specify multiple slots! So the code
should be more like:
(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)))))
(defun slots-for-initarg (initarg class-initargs)
(loop for (slot . initargs) in class-initargs
appending (when (member initarg initargs)
(list slot))))
(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
do (loop
for init-slot in (slots-for-initarg init-arg class-initargs)
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))))))
Of course, it would be much easier to just iterate over all slots and
set those which are not cells but should be to c-in, but there is
"initarg" in the subject after all.
Regards,
Jakub Higersberger
On Wed, Jul 1, 2009 at 7:53 AM, Ramarren<ramarren at gmail.com> wrote:
> 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