'''An Introduction To [Tcl] [Scripting]''', by [John Ousterhout], with some where necesary to reflect modern Tcl. ** See Also ** [Beginning Tcl]: ** Tcl/[Tk] Tutorial, Part II: Language Overview ** Two parts to learning Tcl: 1. '''Syntax and substitution rules:''' * Substitutions are simple, but may be confusing at first. 2. '''Built-in commands:''' * Can learn individually as needed. * Control structures are commands, not language syntax. ---- Basics: Tcl script = * Sequence of ''commands''. * Commands separated by newlines, semicolons. Tcl command = * One or more ''words'' separated by white space. * First word is ''command name'', others are ''arguments''. * Returns ''string result''. Examples: ====== set a 22; set b 33 set a 22 set b 33 ====== ---- Division Of Responsibility The Tcl Parser * Chops commands into words. * Makes substitutions. * ''Does not interpret values of words''. The Command Procedure * Interprets words. * Produces string result. The substitutions carried out by the parser are "one step"; the values substituted are not scanned again for text that looks like substitutions. Some specific commands ([[`[eval]`], [[`[expr]`], [[`[subst]`], ...) perform another round of substitution on their arguments. ---- Arguments * Parser assigns no meaning to arguments (quoting by default, evaluation is special): [C]: ======c x = 4; y = x+10; ====== Result: y is `14` Tcl: ====== set x 4; set y x+10 ====== Result: y is `x+10` * Different commands assign different meanings to their arguments: ====== set a 122 expr 24/3.2 eval "set a 122" button .b -text Hello -fg red string length Abracadabra ====== ---- Variable Substitution * Syntax: $varName * Variable name is letters, digits, underscores, and the namespace separator "::". * May occur anywhere in a word. ======none Sample command Result set b 66 66 set a b b set a $b 66 set a $b+$b+$b 66+66+66 set a $b.3 66.3 set a $b4 no such variable ====== ---- Command Substitution * Syntax: [[''script''] * Evaluate script, substitute result. * May occur anywhere within a word. ====== set b 8 #-> 8 set a [expr {$b+2}] #-> 10 set a "b-3 is [expr {$b-3}]" #-> b-3 is 5 ====== ---- Controlling Word Structure * Words break at white space and semi-colons, except: ** Double-quotes prevent breaks: ====== set a "x is $x; y is $y" ====== ** Curly braces prevent breaks and substitutions: ====== set a {[expr {$b*$c}]} ====== ** Backslashes quote special characters: ====== set a word\ with\ \$\ and\ space ====== * Substitutions don't change word structure: ====== set a {two words} set b $a ====== ---- Expressions * C-like (int and double), extra support for string operations. * Command, variable substitution occurs within expressions. * Used in expr, other commands. ======none Sample command Result set b 5 5 expr ($b*4) - 3 17 expr $b <= 2 0 expr $a * cos(2*$b) -5.03443 expr {$b * [fac 4]} 120 set a Bill Bill expr {$a < "Anne"} 0 ====== ---- Lists * Zero or more elements separated by white space: ====== red green blue ====== * Braces and backslashes for grouping: ====== a b {c d e} f one\ word two three ====== * List-related commands: [concat]: [lindex]: [llength]: [lsearch]: [foreach]: [linsert]: [lrange]: [lsort]: [lappend]: [list]: [lreplace]: * Examples: ====== lindex {a b {c d e} f} 2 #-> c d e lsort {red green blue} #-> blue green red ====== ---- Control Structures * C-like appearance. * Just commands that take Tcl scripts as arguments. * Example: list reversal. ====== set b {} set i [expr [llength $a] - 1] while {$i >= 0} { lappend b [lindex $a $i] incr i -1 } ====== * Commands: [if]: [for]: [switch]: [break]: [foreach]: [while]: [eval]: [continue]: ---- Procedures * [[`[proc]`] defines a procedure: ======none proc sub1 x {expr $x-1} ^ ^ ^ | | | name | body | list of argument names ====== * Procedures behave just like built-in commands: ====== sub1 3 -> 2 ====== * Arguments can have defaults: ====== proc decr {x {y 1}} { expr $x-$y } ====== * Scoping: local and global variables. * Variable-length argument lists: ====== proc sum args { set s 0 foreach i $args { incr s $i } return $s } sum 1 2 3 4 5 #-> 15 sum #-> 0 ====== ---- Errors * Errors normally abort commands in progress, application displays error message: ====== set n 0 foreach i {1 2 3 4 5} { set n [expr {$n + i*i}] } #-> syntax error in expression "$n + i*i" ====== * Global variable [errorInfo] provides stack trace: ====== set errorInfo ====== result: ======none syntax error in expression "$n + i*i" while executing "expr {$n + i*i}" invoked from within "set n [expr {$n + i*i}]..." ("foreach" body line 2) ... ====== ---- Advanced Error Handling * Can intercept errors: ====== catch {expr {2 +}} msg #-> 1 set msg #-> syntax error in expression "2 +" ====== * Can generate errors: ====== error "bad argument" ====== * Global variable [errorCode] holds machine-readable information about errors (e.g. UNIX errno value). ---- Additional Tcl Features: * String manipulation commands: [regexp]: [format]: [split]: [string]: [regsub]: [scan]: [join]: * File I/O commands: [open]: [gets]: [seek]: [flush]: [glob]: [close]: [read]: [tell]: [cd]: [puts]: [source]: [eof]: [pwd]: * Subprocesses with [exec] command: ====== exec grep foo << $input | wc ====== * Associative arrays: ====== set x(fred) 44 set x(2) [expr $x(fred) + 6] array names x #-> fred 2 ====== * Variable scoping: [global]: [uplevel]: [upvar]: * Access to Tcl internals: [info]: [rename]: [trace]: * Autoloading: ** unknown procedure invoked when command doesn't exist. ** Loads procedures on demand from libraries. ** Uses search path of directories. * Additional features: ** Dynamic loading of binaries: load command. ** Security: Safe-Tcl. ** Event-driven I/O. ** Socket support. ---- More On Substitutions * Keep substitutions simple: use commands like format for complex arguments. * Use `{*}` or [[`[eval]`] for another level of expansion: ====== exec rm *.o ;#-> *.o: No such file or directory glob *.o ;#-> a.o b.o exec rm [glob *.o] ;#-> a.o b.o: No such file or directory exec rm {*}[glob *.o] eval exec rm [glob *.o] ====== ----Commands And Lists: [Tcl Quoting] * Lists parse cleanly as commands: each element becomes one word. * To create commands safely, use [[`[list]`] commands: ====== button .b -text Reset -command {set x $initValue} ;#(initValue read when button invoked) ... -command "set x $initValue" ;#(fails if initValue is "New York": command is "set x New York") ... -command "set x {$initValue}" ;#(fails if initValue is "{": command is "set x {{}") ... -command [list set x $initValue] ;#(always works: if initValue is "{" command is "set x \{") ====== ---- Tcl Syntax Summary * Script = commands separated by newlines or semicolons. * Command = words separated by white space. * `$` causes variable substitution. * `[[]` causes command substitution. * `""` quotes white space and semi-colons. * `{}` quotes all special characters. * `\` quotes next character, provides C-like substitutions. * `#` for comments (must be at beginning of command). <> Tutorial