Slots in layers, was Re: [closer-devel] ContextL design question...
Drew Crampsie
drewc at tech.coop
Fri Mar 3 02:42:05 UTC 2006
Pascal Costanza wrote:
>
> I haven't extended the with-active-layers construct, though. Here are
> the reasons:
> - It would really only look neat when used with initargs instead of
> accessors. However, the mapping of initargs to actual slots can be
> changed at runtime in CLOS, so I would have to emit code with quite
> some overhead here that would determine the current mapping of an
> initarg to its actual slot. Worse, an initarg could actually be
> mapped to more than one slot, which would complicate the code even
> further, with very little reward. I wanted to avoid that.
Sounds like my WITH-SPECIAL-INITARGS construct, which has all the
drawbacks you mentioned, but simplifies the implementation of
Lisp-on-Lines significantly.
it's used like this like this :
(with-special-initargs (object :some-initarg value :some-other-initarg
another-value)
...)
Below is the implementation. Use it however you want :)
(defmethod initargs.slot-names (object)
"Returns ALIST of (initargs) . slot-name."
(nreverse (mapcar #'(lambda (slot)
(cons (closer-mop:slot-definition-initargs slot)
(closer-mop:slot-definition-name slot)))
(closer-mop:class-slots (class-of object)))))
(defun find-slot-names-from-initargs-plist (object initargs-plist)
"returns (VALUES SLOT-NAMES VALUES), Given a plist of initargs such as
one would pass to :DEFAULT-INITARGS.
SLOT-NAMES contains the slot-names specified by the initarg, and VALUES
the corresponding VALUE."
(let (slot-names values
(initargs.slot-names-alist (initargs.slot-names object)))
(loop for (initarg value) on initargs-plist
do (let ((slot-name
(cdr (assoc-if #'(lambda (x) (member initarg x))
initargs.slot-names-alist))))
(when slot-name ;ignore invalid initargs. (good idea/bad idea?)
(push slot-name slot-names)
(push value values)))
finally (return (values slot-names values)))))
(defun funcall-with-special-initargs (object initargs function &rest args)
"Call FUNCTION with dynnamic bindings of the slots in OBJECT specified
by the INITARGS plist"
(multiple-value-bind (slot-names values)
(find-slot-names-from-initargs-plist object initargs)
(special-symbol-progv
(with-symbol-access
(loop for slot-name in slot-names
collect (slot-value object slot-name)))
values
(apply function args))))
(defmacro with-special-initargs ((object &rest initargs) &body body)
`(funcall-with-special-initargs ,object ,initargs
#'(lambda ()
, at body)))
More information about the closer-devel
mailing list