set myString "This is a string with \[special characters\}"
if $myString=="" {puts "empty string"}will generate a syntax error. The first line assigns a string with special characters to the variable myString, which is fine. The problem is on the second line. First, the Tcl interpreter breaks the command into three words and performs substitutions. In Tcl syntax, you could think of this as$word1 $word2 $word3where these words are (using >> and << to quote the strings)
word1 is >>if<< word2 is >>This is a string with [[special characters}==""<< word3 is >>puts "empty string"<<Note that the second and third words contain embedded spaces, quotes, and other special characters, but they are really just three words.[I also note the double >>[[<< in word2. Where did that come from?] [And getting the right number of brackets in that line was tricky! ;-]Now the interpreter assumes that the first word is a command (if), and it calls that command, passing in the other words as arguments. The if command treats its first argument as an expression. The expression has seven arguments (This is ...) and if you read the expr man page, you'll see that it will try to perform its own set of substitutions. This causes an error, because the string contains unbalanced braces and brackets. This is the double-substitution that I mentioned earlier. The Tcl interpreter performs one substitution, and expr tries to do another.The answer, of course, is to surround your if expression with braces. Like this:
if {$myString==""} {puts "empty string"}Tcl performs its round of substitutions, and $word1 $word2 $word3 become:word1 is >>if<< word2 is >>$myString==""<< word3 is >>puts "empty string"<<Now when the interpreter calls the if command, the first argument is interpreted as an expression, and the second round of substitutions expands $myString. Then the expression works perfectly.In summary, use braces on if and while and expr expressions. Use ProCheck to make sure you haven't missed any.
KBK - Another point that should be made is that braced expressions on [if], [while] and [expr] aren't just safer, they're also much, much faster. Unbraced ones have to be parsed at run time; braced ones can be compiled down to very tight bytecode sequences.
