In Tcl the words in a command are always exposed to two layers of interpretation: First, Tcl [dodekalogue%|%interprets them] and prepares them as arguments to a routine. Second, the routine interprets those arguments according to its own principles. '''double [substitution]''' occurs when Tcl performs substitutions on original command and a routine then performs substitutions on the resulting arguments. Care is required in these cases to avoid errors, including vulnerability to [injection attack%|%injection attacks]. ** See Also ** [Brace your expr-essions]: Since `[expr]` concatenates its arguments, passing one word enclosed in braces prevents Tcl from performing substitutions on the word. However, when [Tcl Quoting%|%composing a script] programatically don't make the mistake though of thinking that braces turn any value into a [list] and thus give it the proper format to be substituted into the script. [eval]: Discusses proper quoting. [static syntax analysis]: Analysing script content prior to its execution. ** Description ** Tcl interprets each [command] in the following way: It parses the [command], performs [substitution%|%substitutions] on each [word] in the command, [{*}%|%expands] any words marked for expansion, and then calls the [routine] named by the first word of this prepared command, passing the remaining words to the routine as arguments. The routine in turn might subject those arguments to further interpretation. For example, routines like `[eval]` and `[subst]` [concat%|%concatenate] their arguments into a [script] to be evaluated and then pass that script back to Tcl for another round of interpretation and evaluation. `[expr]`, `[if]`, and `[while]` interpret their arguments according to the grammar of `[expr]`, resulting in another round of [variable substitution%|%variable] and [script substitution] . '''Double substitution''' refers to the substitution that happens in the course this further interpretation. Double substitution can be useful but is more often the result of inadvertently neglecting to [Brace your expr-essions%|%quote] the arguments to `[expr]`, `[if]`, and `[while]`. [static syntax analysis] tools can be used to identify double substitution in a script. If a single quoted expression is passed to `[if]`, `[while]`, and `[expr]` those routines can be much more efficient because the expression is parsed and [bytecode%|%compiled], and the resulting bytecode cached in the value for reuse. '''Routines that interpret their arguments as [script%|%scripts] or [expr%|%expressions]''': `[after]`: The second argument is a script to be evaluated later. `[apply]`: The second item of the first argument is a [script]. `[eval]`: [concat%|%concatenates] its arguments into a [script] and evalutes it. `[expr]`: Concatenates is arguments into an expression, in which `$` indicates [variable substitution], and `[[` indicates [script substitution]. `[expr]` is an example of a routine whose arguments represent a distinct language embedded into a Tcl script, and that language in turn allows a Tcl script to be embedded into it. It's Linguaception. `[for]`: The first, third, and last arguments are evaluated as [script%|%scripts], and the second argument is evaluated as an [expr%|%expression]. `[if]`: The ''condition'' arguments are [expr%|%expressions] and the ''body'' arguments are [script%|%scripts]. `[proc]`: The last argument as a [script]. `[trace]`: The last argument is a [script] to be evaluated. `[uplevel]`: [concat%|%Concatenates] its arguments into a [script] and evaluates it. `[while]`: The second argument is an [expr%|%expression] and the third argument is a `[script]`. '''Routines that perform their own particular interpreation of their arguments''': `[set]`: `(` accesses a [variable] in an [array]. `[list]`: `[list]` itself doesn't treat its arguments as anything in particular, but it does format them into items in a list. In a list, `\` `"` and `{` operate the same way they do in Tcl. Tcl is designed this way so that a list is a properly-formatted command. `[regexp]` and `[regsub]`: Some arguments are [regular expressions]. `[string match]`: `*`, `?`, `[`, and `\` have special meaning. To use these routines correctly it is necessary to understand how they interpret their arguments, and then [Tcl quoting%|%quote] arguments to that routine accordingly. The [dodekalogue%|%standard rules of Tcl%|%] describe the syntax of Tcl, and each additional routine documents its own interpretation and treatment of its arguments. Arguments to `[expr]` should almost [brace your expr-essions%|%always be quoted somehow] so that Tcl doesn't perform any substitutions on them. Typically braces are the most convenient but any form of quoting that prevents substitution is sufficient. The same is true for the first argument to `[if]` and `[while]`, and for arguments of other routines as listed above. This is mentioned on the [Tcl Style Guide] page and is discussed a bit on [A Question of Style]. One common mistake is to let Tcl substitute a variable: ====== set myString hello #This doesn't work: if "$myString eq {}" {puts {empty string}} ====== Tcl substitutes `$myString`, so the expression looks like this: ====== hello eq {} ====== `hello` is not quoted, which is an error because an expression requires strings to be quoted. The expression evaluator should perform the substitution instead: ====== set myString hello if {$myString eq {}} {puts {empty string}} ====== *** A complex example *** In the following example, there are many issues: ====== #warning: bad code ahead! set myString "This is a string with \[special characters\}" if $myString eq {} {puts {empty string}} ====== The value passed as an expression is ====== This is a string with [special characters} eq {} ====== , which makes no sense as an [expr%|%expression]. Additionally, there is no corresponding right square bracket for the left square bracket that signals [script substitution], and no corresponding left curly bracket for the right curly bracket. The best course of action is to prevent the Tcl substitutions with curly braces: ====== if {$myString eq {}} {puts {empty string}} ====== Now the value passed as an [expr%|%expression] is [expr%|%expression]: ====== $myString eq {} ====== , which is syntactically correct. ** Page Authors ** [KBK]: [PYK]: <> String Processing