Substituting Command Names

Try this:

set DontPrintString puts
$DontPrintString "I told you not to print this!\n"

It prints it anyway.

Why? Because the variable DontPrintString was evaluated in the substitution pass, "puts" was substituted, and then it was evaluated.

So What? I'm not sure. Try this:

proc PrintOrExpr {a b} {
    if { [string compare $a "print"] } {
        set cmdname expr
    } else {
        set cmdname puts
    }
    $cmdname $b
}

This example isn't useful, but the technique has got to be good for something...

pdm

LV Paul, one place I use something like this is in ... hmm, what is that page name. Basically, it was a tcl script to take create csv records containing file info like ls would return. I use a variable for the output commands so that I could turn on debugging and all of a sudden the output goes elsewhere...

RS You can even use a command in command name substitution. For instance, if you have created some procs with long names and want to call them interactively, you can instead say

[info proc A*] arg1 arg2...

If there is exactly one proc starting with "A", this works. In any other case you'll get an instructive error message. See Searching A Star in Space where I use this technique for uniquifying a proc name.

pdm In C we use function pointers quite a bit at work. They are useful for speed (to eliminate a bunch of if statements) and for cleaner code (ditto). Command name substitution could be used in a similar way.

The tradeoff, I guess, is that it is a little more confusing. We have the same problem with function pointers in C. The TCL syntax is easier to remember, though.