CLIM mail archive
[Prev][Next][Index][Thread]
Using DEFINE-COMMAND
Date: Fri, 8 Mar 1991 11:36 EST
From: David C. P. Linden <DCPL@fuji.ila.com>
Date: Thu, 21 Feb 91 10:36 EST
From: Jeff Morrill <jmorrill@bbn.com>
I am using CLIM 0.9.54 to define a system that is not
an application per se, but rather a toolbox that gets
embedded in other applications. One of the things that
the applications inherit is of course a command table.
What is the "canonical" way to define commands that
are not associated with any single application? I started
off doing something like
(define-command com-print-number
((object 'number))
(print object))
(add-command-to-command-table "Print Number"
'com-print-number 'my-comtab)
But one quickly discovers that EXECUTE-COMMAND funcalls
the command using the application frame as a first, hidden
argument. (WHY?) It would appear that I should be using
DEFINE-FRAME-COMMAND instead, which adds the hidden frame
argument invisibly:
(define-frame-command my-comtab com-print-number
((object 'number))
(print object))
I suppose it makes sense to have the frame as a hidden
argument, since there is no special binding such as
dw:*program-frame*. So should user code ever invoke
DEFINE-COMMAND?
In 0.9, there are three things that D-F-C does over D-C:
-- D-F-C can provide automatic ways of adding the command to the
frame's command table.
-- D-F-C gives the code access to the frame associated with this
invocation of the command, whereas D-C should not assume anything
about particular frames.
-- D-F-C allows the same command to exist on several frames, e.g.,
COM-EXIT, and to write :before/:after/:around methods for the
command.
The first is a convenience. It is the interaction of the last two that
is troubling you. The third is accomplished by defining the command as
a method on the frame type, so the frame type is a CLOS specializer and
thus must be present. That makes the second easy: since the frame is an
argument the forms WITH-FRAME and WITH-FRAME-SLOTS simply reference that
argument. That's the way it exists today.
It is worth reviewing which of those semantic differences between D-F-C
and D-C are desirable. Since the first is a convenience, it shouldn't
have any implementation impact. There are other ways of accomplishing
the second, e.g., with a concept similar to dw:*program-frame*. I don't
know if the third has actually been exploited, and this is where
customer feedback would help. If it was a "We can do this, let's try
it" and nobody uses it, it might be flushable and we can then let users
intermix usages of D-F-C and D-C. Until now, I didn't realize the third
semantic difference existed, and for me the bookkeeping overhead to make
sure I wasn't making mistakes would prevent me from trying to.
Unfortunately, this may not be patchable into a world that has already
done DEFINE-FRAME-COMMAND (and DEFINE-/frame-type/-COMMAND) without
finding and redoing all those DEFINE-FRAME-COMMANDs. I.e., the changes
would be compatable at the user source level, but not the user binary
level. I'll make a note of this for consideration for CLIM 2.0 in the
event it isn't reorganized for 0.9. (I don't know what 1.0 does.)
In CLIM Release 1.0, Moon and I (with Dennis reviewing) decided that
having some commands that take a "hidden" frame argument while having
others that did not was just a source for bugs and confusion.
Therefore, in CLIM Release 1.0, commands do not take a hidden frame
argument, and are implemented as ordinary functions.
DEFINE-COMMAND takes a :COMMAND-TABLE option to allow you to insert a
command into a command table. DEFINE-frame-name-COMMAND just supplies
:COMMAND-TABLE frame-name for you; it is merely a convenience macro, and
otherwise has exactly the same semantics as DEFINE-COMMAND.
Furthermore, at all times, the variable *APPLICATION-FRAME* is guaranteed
to be bound to the frame you are currently in. An around method on
RUN-FRAME-TOP-LEVEL does this for you.
As you can deduce, we decided to give up on specializing frame commands,
but importing commands wholesale from one command table to another is
very easily done. Moon and I both agreed that that would be adequate
for most things.
0,,
References:
Main Index |
Thread Index