Many ways to eval

Many commands evaluate their arguments as Tcl scripts. This page, by Andreas Leitgeb, dgp, ms, pyk, rs, et al, enumerates those commands.

Description

As implied by its name, eval is the most explicit way to evaluate an arguments as a script. In the following example, every command (except the first, of course, does the same thing: evaluates $cmd as a script.

set cmd {set name {Zaphod Beeblebrox}}

#these examples are not byte-compiled, so slower
eval $cmd
uplevel 0 $cmd
history add $cmd exec
source nameoffile

#these examples are byte-compiled, so faster
if 1 $cmd
interp eval {} $cmd
namespace eval [namespace current] $cmd
switch 1 1 $cmd
for {} "\[info cmdcount] < [info cmdcount] + 3" {} $cmd 
proc {} {} [list uplevel $cmd]; {}
apply [list {} [list uplevel $cmd] [namespace current]]
apply [list argv {tailcall {*}$argv} [namespace current]] $argv

MS explained: "... eval does not bytecompile the script, as it is "usually" used for one-time scripts.

The above examples all act like eval in the sense that they return the result of evaluating the script. The commands in the following example evaluate the string as a script, but don't return the result of the script:

foreach don't care $cmd
while 1 "$cmd; break"
interp alias {} breakable {} foreach _ _
breakable $cmd
catch $cmd
time $cmd
try $cmd

Taking it one step further, the following evaluation tactics not only don't return the result of evaluating the script, but don't evaluate it in the namespace they are called from:

after idle $cmd

Commands That Evaluate Scripts

after
catch
chan event / fileevent
dict for
dict map
dict update
dict with
eval
for
foreach
history add script exec
history redo event
if
interp eval
lmap
namespace eval
namespace inscope
source
switch
time
try
uplevel
while

Commands that Express

The followig commands execute Tcl scripts that are operands in an exression:

expr
for
if
while

Commands That Execute Commands

apply
interp alias
lsort -command
my
next and nextto
tailcall

Commands that Arrange To Execute Commands

unknown
namespace unknown
namespace ensemble configure ... -map ...
namespace ensemble configure ... -unknown ...
namespace ensemble configure ... -subcommands ...
trace
yieldto

subst

subst is in a category of its own, as it results in the evaluation in arbitrary text of substrings that can be interpreted as command or variable substitutions:

subst {Why do {[set a {my eyes}]} ; hurt?}

In the example above, braces did not escape the command-substitution meaning of brackets. subst is probably the most misused command in Tcl.

See Also

Creating Commands
enumerates and compares the commands which create commands
Injection Attack
Any command that results in evaluation of arbitrary strings is potentially vulnerable to injection attacks. Well-written code always uses such commands in a way that precludes this class of attack.
Tcl chatroom, 2002-12-18