
arguments passing with exec
Quote:
>> Optimization is really a secondary issue; [eval exec myExe $cmd]
>> can break badly if $cmd is not in canonical form.
>> [linsert $cmd 0 exec myExe] forces it to be so.
>Let me see if I can get this straight. This code:
> % set cmd "foo bar {"
> foo bar {
> % eval puts $cmd
>gives me a "missing close-brace" error because $cmd isn't a proper list.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Not quite: it breaks because the string [concat "puts" "$cmd"]
(which is what [eval] constructs internally) is not a well-formed script.
For instance the following works just fine:
set part1 "puts { foo bar"
set part2 "baz blech }"
eval $part1 $part2
even though neither $part1 nor $part2 is a valid (let alone proper) list.
Quote:
>However,
> % set cmd "foo bar {"
> foo bar {
> % eval [linsert $cmd 0 puts]
>breaks too!
*This* one breaks because $cmd isn't a well-formed list.
(Here it's [linsert] that raises the error, because it
expects a list as its first argument.)
Quote:
> Is that what you were referring to?
The usual problem I run into with [eval $cmd $args] is when
$args is a valid list, but not necessarily in canonical form.
For instance:
set options {
-foreground purple
-background green
-font Garish-20
}
$options is a valid list -- it works with [lindex], [lappend], [lrange]
and all the other list functions -- but [eval .t tag configure foo $options]
breaks because of the embedded newlines.
[linsert $options 0 .t tag configure] returns a canonical list,
which [eval] will interpret as a single command, as desired.
Quote:
>(But eval puts [list $cmd] works).
Right: [list $cmd] returns a canonical list (containing one element).
A property of Tcl is that, although [concat] operates on strings and
not lists, if $l1 and $l2 are canonical lists then [concat $l1 $l2] is
also a canonical list. Another property of Tcl is that if $l1 is a
canonical list, then $l1, when interpreted as a script, will consist
of a single command.
(The optimization mentioned earlier in this thread takes advantage
of the second property: if $l is a pure list, then [eval $l] can skip
converting $l to a string and re-parsing it as a script.)
But it's important to remember that [eval] works on *strings*, not
lists, and the rules for interpreting a string as a list are
different than the rules for interpreting a string as a script.
--Joe English