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

Aliasing Tcl procedures

483 views
Skip to first unread message

David Megginson

unread,
Apr 30, 1994, 8:23:28 AM4/30/94
to
The "rename" command allows you to change the name of a Tcl procedure,
but it eliminates the reference from the earlier name -- for example,
if I use "rename foo bar", "foo" is no longer a valid procedure name.
Is there any way in regular Tcl (_not_ TclX, etc) to alias a
procedure, so that both names are valid? I have written the following
procedure, but it is quite inefficient in its resource usage:

proc alias {old new} {
set oldArgs [info args $old]
set newArgs {}

foreach arg $oldArgs {
if [info default $old $arg default] {
lappend newArgs [list $arg $default]
} else {
lappend newArgs $arg
}
}
proc $new $newArgs [info body $old]
}

Does anyone have a better plain-Tcl solution?


Thanks,

David
--
---
David Megginson Department of English, University of Ottawa,
dmeg...@aix1.uottawa.ca Ottawa, Ontario, CANADA K1N 6N5
dmeg...@acadvm1.uottawa.ca Phone: (613) 564-6850 (Office)
ak...@freenet.carleton.ca (613) 564-9175 (FAX)

Gerald W. Lester

unread,
May 2, 1994, 1:53:31 PM5/2/94
to
In article <DMEGGINS.94...@aix1.uottawa.ca>, dmeg...@aix1.uottawa.ca (David Megginson) writes:
>The "rename" command allows you to change the name of a Tcl procedure,
>but it eliminates the reference from the earlier name -- for example,
>if I use "rename foo bar", "foo" is no longer a valid procedure name.
>Is there any way in regular Tcl (_not_ TclX, etc) to alias a
>procedure, so that both names are valid? I have written the following
>procedure, but it is quite inefficient in its resource usage:
>
> proc alias {old new} {
> set oldArgs [info args $old]
> set newArgs {}
>
> foreach arg $oldArgs {
> if [info default $old $arg default] {
> lappend newArgs [list $arg $default]
> } else {
> lappend newArgs $arg
> }
> }
> proc $new $newArgs [info body $old]
> }
>
>Does anyone have a better plain-Tcl solution?
>
You could do:

proc alias {old new} {
proc $new {args} "uplevel 1 \[concat \[list {$old} \] \$args\]"
}

I'm not sure if it "better".


==========================================================================
* Gerald W. Lester ! Voice: (504)-889-2784 *
* Computerized Processes Unlimited ! FAX: (504)-889-2799 *
* 4200 S. I-10 Service Road, Suite #205 ! E-Mail: g...@cpu.com *
* Metairie, LA 70001 ! *
==========================================================================

Gustaf Neumann

unread,
May 1, 1994, 4:10:17 PM5/1/94
to
In article <DMEGGINS.94...@aix1.uottawa.ca> from [30 Apr 1994 12:23:28 GMT] you wrote:
|> The "rename" command allows you to change the name of a Tcl procedure,
|> but it eliminates the reference from the earlier name -- for example,
|> if I use "rename foo bar", "foo" is no longer a valid procedure name.
|> Is there any way in regular Tcl (_not_ TclX, etc) to alias a
|> procedure, so that both names are valid? I have written the following
|> procedure, but it is quite inefficient in its resource usage:

The following procedure is used in Wafe for implementing aliasing in C.
Once the alias is defined, it has no runtime overhead compared with
the real command.

Since this is take straight out of wafe, you will need for the
compilation tclInt.h and it is necessary to strip out the DBUG statements
and replace wafeInterpreter by an argument passed to alias() or similar.
Nearly half of the code below was automatically generated
by Wafe's c code generator.

-gustaf

/*
* the real work
*/

static int
alias(newCmdName,oldCmdName)
String newCmdName;
String oldCmdName;
{
XtPointer cmdPtr;
Interp *iPtr = (Interp *) wafeInterpreter;
Tcl_HashEntry *hPtr;
int new;

if ((hPtr = Tcl_FindHashEntry(&iPtr->commandTable, newCmdName)) != NULL)
{
fprintf(stderr,
"Wafe(alias): can't alias to '%s': command already exists\n",
newCmdName);
/* Tcl_AppendResult(wafeInterpreter, "can't alias to \"", newCmdName,
"\": command already exists", (char *) NULL); */
return 0;
}

if ((hPtr = Tcl_FindHashEntry(&iPtr->commandTable, oldCmdName)) == NULL)
{
fprintf(stderr,
"Wafe(alias): can't alias '%s': command doesn't exist\n",
oldCmdName);
/* Tcl_AppendResult(wafeInterpreter, "can't alias \"", oldCmdName,
"\": command doesn't exist", (char *) NULL); */
return 0;
}

cmdPtr = (XtPointer) Tcl_GetHashValue(hPtr);
hPtr = Tcl_CreateHashEntry(&iPtr->commandTable, newCmdName, &new);
Tcl_SetHashValue(hPtr, cmdPtr);
return 1;
}

/*
* argument passing
*/
static int
cmd_alias(clientData, comInterpreter, argc, argv)
ClientData clientData;
Tcl_Interp *comInterpreter;
int argc;
char **argv;
{
int returnVar;
char conversionBuffer[100];

DBUG_ENTER("alias");

if (argc != 3)
{
wafeArgcError("alias","",2,argc);
DBUG_RETURN (TCL_ERROR);
}
sprintf(conversionBuffer, "%d", returnVar);
Tcl_SetResult(comInterpreter, conversionBuffer, TCL_VOLATILE);

DBUG_RETURN (TCL_OK);
}

/*
* command registration
*/
...
Tcl_CreateCommand(wafeInterpreter, "alias", cmd_alias, NULL, NULL);
...

--
Gustaf Neumann neu...@watson.ibm.com
Postdoctoral/Visiting Scientist Tel: (914) 784 7086
IBM T.J.Watson Research Center, P.O.Box 704
Yorktown Heights, New York 10598

John Ousterhout

unread,
May 5, 1994, 12:14:57 PM5/5/94
to
In article <1994May2.1...@cpu.com>, gwle...@cpu.com (Gerald W. Lester) writes:
|> In article <DMEGGINS.94...@aix1.uottawa.ca>, dmeg...@aix1.uottawa.ca (David Megginson) writes:
|> >The "rename" command allows you to change the name of a Tcl procedure,
|> >but it eliminates the reference from the earlier name -- for example,
|> >if I use "rename foo bar", "foo" is no longer a valid procedure name.
|> >Is there any way in regular Tcl (_not_ TclX, etc) to alias a
|> >procedure, so that both names are valid? I have written the following
|> >procedure, but it is quite inefficient in its resource usage:
|> >
|> >...

|> >
|> >Does anyone have a better plain-Tcl solution?
|> >
|> You could do:
|>
|> proc alias {old new} {
|> proc $new {args} "uplevel 1 \[concat \[list {$old} \] \$args\]"
|> }
|>
|> I'm not sure if it "better".
|>

I'm afraid this probably isn't better. It may work in most cases, but
if "old" contains special characters then it won't work. For example,

alias "{foo" bar

will not work. This is another example of "quoting hell", where you
are trying to generate valid Tcl commands with arbitrary fields by
using substitutions. This doesn't work in general: you have to assemble
such scripts with the list commands, not with substitutions. See
Section 6.7 of the Tcl book for details (page 68-69).

0 new messages