**More command construction - format, list** !!!!!! '''[Tcl Tutorial Lesson 32%|%Previous lesson%|%]''' | '''[Tcl Tutorial Index%|%Index%|%]''' | '''[Tcl Tutorial Lesson 34%|%Next lesson%|%]''' !!!!!! There may be some unexpected results when you try to compose command strings for `eval`. For instance: ====== eval puts OK ====== would print the string OK. However, ====== eval puts Not OK ====== will generate an error. The reason that the second command generates an error is that the `eval` uses `concat` to merge its arguments into a command string. This causes the two words `Not OK` to be treated as two arguments to `puts`. If there is more than one argument to `puts`, the first argument must be a file pointer. Correct ways to write the second command include these: ====== eval [list puts {Not OK}] eval [list puts "Not OK"] set cmd "puts" ; lappend cmd {Not OK}; eval $cmd ====== As long as you keep track of how the arguments you present to `eval` will be grouped, you can use many methods of creating the strings for `eval`, including the `string` commands and `format`. The recommended methods of constructing commands for `eval` is to use the `list` and `lappend` commands. These commands become difficult to use, however if you need to put braces in the command, as was done previously. The earlier example is re-implemented in the example code using `lappend`. The completeness of a command can be checked with `info complete`. `info complete` can also be used in an interactive program to determine if the line being typed in is a complete command, or the user just entered a newline to format the command better. `info complete string`: If `string` has no unmatched brackets, braces or parentheses, then a value of 1 is returned, else 0 is returned. ---- ***Example*** Example, part 1 (will produce an error): ====== set cmd "OK" eval puts $cmd set cmd "puts" ; lappend cmd {Also OK}; eval $cmd set cmd "NOT OK" eval puts $cmd ====== <> Resulting output ======none OK Also OK can not find channel named "NOT" while executing "puts NOT OK" ("eval" body line 1) invoked from within "eval puts $cmd" (file "xx.tcl" line 7) ====== <> Example, part 2: ====== eval [format {%s "%s"} puts "Even This Works"] set cmd "And even this can be made to work" eval [format {%s "%s"} puts $cmd ] set tmpFileNum 0; set cmd {proc tempFileName } lappend cmd "" lappend cmd "global num; incr num lappend cmd "return \"/tmp/TMP.[pid].\$num\"" eval $cmd puts "\nThis is the body of the proc definition:" puts "[info body tempFileName]\n" set cmd {puts "This is Cool!} if {[info complete $cmd]} { eval $cmd } else { puts "INCOMPLETE COMMAND: $cmd" } ====== <> Resulting output ======none Even This Works And even this can be made to work This is the body of the proc definition: global num; incr num return "/tmp/TMP.17520.$num" INCOMPLETE COMMAND: puts "This is Cool! ====== <> !!!!!! '''[Tcl Tutorial Lesson 32%|%Previous lesson%|%]''' | '''[Tcl Tutorial Index%|%Index%|%]''' | '''[Tcl Tutorial Lesson 34%|%Next lesson%|%]''' !!!!!!