Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ensembles vs. commands

12 views
Skip to first unread message

Fredderic

unread,
Nov 18, 2007, 2:31:07 AM11/18/07
to
Greetings good people of TCL land...

We have, in 8.5 (now that I've finally got it to play with), the
[namespace ensemble] command, for doing commands of the sort [dict] or
[file]. These use a base command, which takes the thing being
manipulated as an argument to a sub-command. The good part of doing it
this way, is that the thing being manipulated can be either a value or
a name reference, as required by the sub-command. (Or, for that
matter, may not even be required, as in the case of a [thing new]
sub-command.)

But, what's the best way to do the alternative, [$thing command]
style? I generally create a [new] procedure within a namespace, which
creates an array to hold the things innards, and uses [interp alias] to
invoke a [thing::command] procedure within the namespace, that acts as
a sub-command invocation gateway. Some simple stuff it'll usually do
right off the bat with a switch, while more complicated stuff gets
dispatched as a command within the namespace (that rather neatly allows
me to assume some internal naming convention to separate the
sub-commands from first-level command). (A -partial match type to
switch that correctly handles things like "set" vs. "set-here", would
be much appreciated ;) )

I've been looking at improving this with the use of [ensemble]s, but
this won't achieve very much. The [interp alias] way generally
requires that $thing be the first argument before the sub-command.
[ensemble], however, requires that the sub-command be first. So I'd
still need a [thing::command] wrapper to handle the translation,
although now much simpler than before. Or am I missing something?


On the assumption that I haven't, has anyone perchance tip'd an option
to [ensemble create] to let the first n arguments be arguments, with the
sub-command following that? (Or alternatively, an option to specify
which argument is the sub-command, instead of requiring it to be the
first.) Doing that would allow you to create two ensembles, one for
the top-level functions like [new], and a second to handle actions
applied to the commands created by [new], simply by having [new]
generate an [interp alias] to the second ensemble.


Fredderic

Donal K. Fellows

unread,
Nov 19, 2007, 5:26:29 AM11/19/07
to
Fredderic wrote:
> On the assumption that I haven't, has anyone perchance tip'd an option
> to [ensemble create] to let the first n arguments be arguments, with the
> sub-command following that? (Or alternatively, an option to specify
> which argument is the sub-command, instead of requiring it to be the
> first.) Doing that would allow you to create two ensembles, one for
> the top-level functions like [new], and a second to handle actions
> applied to the commands created by [new], simply by having [new]
> generate an [interp alias] to the second ensemble.

I think you'll want to read carefully about the -map option. :-)

Donal.

Fredderic

unread,
Nov 19, 2007, 11:58:19 AM11/19/07
to

I've read the text on -map a few times, but I still don't see how it
fits my problem... To clarify a little, if I explained it badly, I
presently have something like this;

proc shoop::New {args} {
set id ::shoop::[incr ::shoop::unique-id]
array set $id $::shoop::TEMPLATE
... do mode stuff ...
interp alias {} $id {} shoop::command $id
return $id
}

set myShoop [shoop::New shoopy args]
$myShoop do something
set blah [$myShoop get something]

I rather like this style. [shoop $id blah] is good too, but annoying.
[$id blah] is much lazier, and I like lazier, it takes a little of the
strain off my not-exactly-21-anymore brain.

The problem with -map is that every time you create a new shoop, or
destroy an old one, you'd have to update the map. And even then, it
still needs an [interp alias] to set up, and you still need to have it
invoke a common command, possibly another ensemble, that in turn
invokes the sub-command you're asking for.

As far as I can tell, an intermediary is still required to change
[shoop $id sub args] into [shoop sub $id args], before the ensemble can
properly handle it. Otherwise, [ensemble -map] will still see my $id as
the sub-command, and not as an argument to the sub-command, which is
what I need.


As it stands, I actually add another argument to the [interp alias]
line. The number 2. This quite neatly side-steps the need for an
excessive number of uplevel's, if you just increment the value every
time you pass it down into another procedure. You can then [upvar
$lvl ...] or [uplevel $lvl ...], and have the code skip right back to
the invoking procedure. It really works quite well.


Fredderic

0 new messages