Re: How to provide extra initargs for interfaces?
On 1/9/07, Martin Simmons <martin@lispworks.com> wrote:
>
> >>>>> On Mon, 8 Jan 2007 15:50:08 -0500, Taylor, Joshua said:
> >
> > On 1/8/07, Martin Simmons <martin@lispworks.com> wrote:
> > >
> > > >>>>> On Sat, 6 Jan 2007 00:13:05 -0500, Taylor, Joshua said:
> > > >
> > > > Hello all,
> > > >
> > > > Let's say I'm working on an interface foo which has
> > > > a pane bar-pane which is of type bar. Then I would have
> > > > use a definition something like:
> > > >
> > > > (capi:define-interface foo () ()
> > > > (:panes
> > > > (bar bar-pane)
> > > > ...)
> > > > ...)
> > > >
> > > > Now, the bar-pane class accepts some initargs
> > > > with its make-instance; e.g.,
> > > >
> > > > (make-instance 'bar-pane :option-1 'baz)
> > > >
> > > > Is there a way I can setup an initarg for the
> > > > interface such that I could
> > > >
> > > > (make-instance 'foo :bar-option-1 'baz)
> > >
> > > Yes, this can be done by specifying (:initarg initarg-spec) as a value for the
> > > initarg of the pane. The initarg-spec can be keyword, e.g.
> > >
> > > (capi:define-interface foo () ()
> > > (:panes
> > > (bar bar-pane :bar-option-1 (:initarg :bar-option-1))
> > > ...)
> > > ...)
> > >
> > > or something that can follow &key in a lambda-list, e.g.
> > >
> > > (capi:define-interface foo () ()
> > > (:panes
> > > (bar bar-pane :bar-option-1 (:initarg (bar-option-1 22)))
> > > ...)
> > > ...)
> > >
> > > There is an example of the first case in
> > > examples/capi/graphics/pinboard-test.lisp and we will add it to the
> > > documentation for define-interface.
> > >
> > > --
> > > Martin Simmons
> > > LispWorks Ltd
> > > http://www.lispworks.com/
> > >
> > >
> > This is great! It gets me *almost* everything I want. However,
> > there's one bit that it's still missing for me. If the initarg isn't
> > given, I'd like to see the :initform be used. Consider the following
> > example:
> >
> > (defclass foo (capi:output-pane)
> > ((slot1 :initarg :slot1
> > :initform 3)))
> >
> > (capi:define-interface
> > foo-interface () ()
> > (:panes
> > (f foo
> > :slot1 (:initarg :slot1))))
> >
> > (let ((fi (make-instance 'foo-interface :slot1 5)))
> > (with-slots (f) fi
> > (slot-value f 'slot1)))
> > ; => 5
> >
> > (let ((fi (make-instance 'foo-interface)))
> > (with-slots (f) fi
> > (slot-value f 'slot1)))
> > ; => NIL
> > ; I was hoping to see 3
> >
> > In the second instance of foo-interface, slot1 is set to NIL
> > rather than 5 because the define-interface expands to a
> > make-instance where the value is placed unconditionally.
> > Is there a mechanism for getting something like
> > .. &key (arg value arg-p) .. ?
> >
> > (And if there's not, it's not *all* that bad, but it means that defaults
> > have to be kept in the pane definition as initforms *and* in the
> > interface definition as default initargs; I'd like to have the defaults
> > in just one place. Nonetheless, this is nice to know about.)
>
> There is no direct way to omit the initarg, but see the define-interface
> documentation on the :make-instance-extra-apply-args keyword argument for
> another way to add complete lists of initargs to a pane.
>
Ah, I'd missed that in the docs. This is a useful one to have too. I'll probably
end up using the (:initarg name-of-initarg) option, and just provide a
default-initarg for this application, but it's good to have the flexibility
for future reference. Thanks!
--
=====================
Joshua Taylor
tayloj@rpi.edu
"A lot of good things went down one time,
back in the goodle days."
John Hartford