本文共 4900 字,大约阅读时间需要 16 分钟。
tcl是一种很通用的脚本语言,它几乎在所有的平台上都可以解释运行,其强大的功能和简单精妙的语法会使你感到由衷的喜悦,这片文章对 tcl有很好的描述和说明。极具可读性,我并不是原封不动的翻译而是加上了一些自己的体会和例子,如有错误请指正。如果你看起来很吃力,那是因为 tcl与一般的语言有一些不同之处,刚开始可能有一些不理解,但很快就会掌握的。请坚持一下,我能坚持写完,你至少也应该坚持读一遍吧!tcl overview这篇文章里包含了几乎 tcl 的全部。文章的作者是tcl的缔造者john ousterhout,对tcl的诠释非常清楚。introduction 简介tcl 代表 "tool command language" 发音为 "tickle." 。它实际上包含了两个部分:一个语言和一个库。首先,tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。它有一个简单的语法和很强可扩充性,tcl可以创建新的过程以增强其内建命令的能力。其次,tcl是一个库包,可以被嵌入应用程序,tcl的库包含了一个分析器、用于执行内建命令的例程和可以使你扩充(定义新的过程)的库函数。应用程序可以产生tcl命令并执行,命令可以由用户产生,也可以从用户接口的一个输入中读取(按钮或菜单等)。但tcl库收到命令后将它分解并执行内建的命令,经常会产生递归的调用。/* 现在不理解没关系,请往下看 */应用程序使用tcl作为它的命令语言有三个好处:1 tcl提供了标准语法,一旦用户掌握了tcl就可以很容易的发布命令给基于tcl的程序。2 tcl实现了很多的功能,使你的工作变得很方便。3 tcl可作为程序间通信的接口。tcl interpreters 解释器在tcl的数据结构中的核心是tcl_interp.一个解释器包含了一套命令,一组变量和一些用于描述状态的东西。每一个 tcl命令是在特定的tcl_interp中运行的,基于tcl的应用程序可以同时拥有几个tcl_interp。tcl_interp是一个轻量级的结构,可以快速的新建和删除。tcl data types 数据类型tcl只支持一种数据结构:字符串(string)。所有的命令,命令的所有的参数,命令的结果,所有的变量都是字符串。请牢记这一点,所有的东西都是字符串。然而字符串的实际解释是依赖于上下文或命令的。它有三种形式:命令(command), 表达式(expresion)和表(list)。下面会讨论细节。basic command syntax 基本语法tcl有类似于shell和lisp的语法,当然也有许多的不同。一条tcl的命令串包含了一条或多条命令用换行符或分号来隔开,而每一条命令包含了一个域(field)的集合,域使用空白分开的,第一个域是一个命令的名字,其它的是作为参数来传给它。例如:set a 22 //相当于c中的 a=22 a是一个变量这条命令分为三个域:1: set 2: a 3: 22set使用于设置变量的值的命令,a、20 作为参数来传给它,a使它要操作的变量名,22是要付给的a值。tcl的命令名可以使内建的命令也可以是用户建的新命令,在应用程序中用函数tcl_createcommand来创建。所有的参数作为字符串来传递,命令自己会按其所需来解释的参数的。命令的名字必须被打全,但 tcl解释器找不到一同名的命令时会用 unknown命令来代替。在很多场合下,unknown 会在库目录中搜寻,找到一个的话,会自动生成一个tcl命令并调用它。unknown经常完成缩略的命令名的执行。但最好不要使用。comments 注释和shell很象,第一个字母是'#'的tcl字符串是注释。grouping arguments with double-quotes 用双引号来集群参数用双引号来集群参数的目的在于使用有空白的参数。例如: set a "this string contains whitespace"如够一个参数一双引号来开始,该参数会一直到下一个双引号才结束。其中可以有换行符和分号。子替换是在正式运行该调命令之前由分析器作的variable substitution with $ 用美元符进行变量替换说白了就是引用该变量。如:set a helloset b $a // b = "hello" 实际上传给set命令的参数//是b,"hello"set c a // b = "a"command substitution with brackets 命令子替换(用方括号)例如:set a [set b "hello"]实现执行 set b "hello" 并用其结果来替换源命令中的方括号部分,产生一条新命令set a "hello" //"hello" 为 set b "hello" 的返 //回值最终的结果是b="hello" a="hello" 当命令的一个子域以方括号开始以方括号结束,表示要进行一个命令子替换。并执行该子命令,用其结果来替换原命令中的方括号部分。方括号中的部分都被视为tcl命令。一个复杂一点的例子:set a xyz[set b "abc"].[set c "def"]//return xyzabcdefbackslash substitution 转移符替换转移符时间不可打印字符或由它数意义的字符插入进来。这一概念与c语言中的一样。/b backspace (0x8)./f form feed (0xc)./n newline (0xa)./r carriage-return (0xd)./t tab (0x9)./v vertical tab (0xb)./{ left brace (`{')./} right brace (`}')./[ open bracket (`[')./] close bracket (`]')./$ dollar sign (`$')./sp space (` '): does not terminate argument./; semicolon: does not terminate command./" double-quote. grouping arguments with braces 用花扩括号来集群参数用花扩括号来集群参数与用双引号来集群参数的区别在于:用花扩括号来集群参数其中的三种上述的子替换不被执行。而且可以嵌套。例如: set a {xyz a {b c d}}//set收到俩个参数 a 'xyz a {b //c d}'eval { set a 22set b 33}//eval收到一个参数 'set a 22/nset b 33'command summary 命令综述1.一个命令就是一个字符串(string)。2.命令是用换行符或分号来分隔的。3.一个命令由许多的域组成。第一个于是命令名,其它的域作为参数来传递。4.域通常是有空白(tab横向制表健 space空格)来分开的。5.双引号可以使一个参数包括换行符或分号。三种子替换仍然发生。6.花括号类似于双引号,只是不进行三总体换。7.系统只进行一层子替换,机制替换的结果不会再去做子替换。而且子替换可以在任何一个域进行。8.如果第一个非控字符是`#', 这一行的所有东西都是注释。expressions 表达式对字符串的一种解释是表达式。几个命令将其参数按表达式处理,如:expr、for 和 if,并调用tcl表达式处理器(tcl_exprlong,tcl_exprboolean等)来处理它们。其中的运算符与c语言的很相似。!逻辑非* / % + - << >> 左移 右移 只能用于整数。< > <= >= == != 逻辑比较& ^ |位运算 和 异或 或&& || 逻辑'和' '或'x ? y : z if-then-else 与c的一样tcl 中的逻辑真为1,逻辑假为0。一些例子:5 / 4.05 / ( [string length "abcd"] + 0.0 )---------------------- ---计算字符串的长度 转化为浮点数来计算"0x03" > "2""0y" < "0x12"都返回 1set a 1expr $a+2expr 1+2都返回 3lists 列表字符串的另一种解释为列表。一个列表是类似于结果的一个字符串包含了用空白分开的很多域。例如 "al sue anne john" 是一个有四个元素的例表,在列表中换行父被视为分隔符。例如:b c {d e {f g h}} 是一个有三个元素的列表 b 、c 和 {d e{f g h}}。tcl的命令 concat, foreach, lappend, lindex, linsert,list, llength, lrange,lreplace, lsearch, 和 lsort 可以使你对列表操作。regular expressions 正则表达式tcl 提供了两个用于正则表达式的命令 regexp 和 regsub。这里的正则表导师实际上是扩展的正则表达式,与 egrep 相一致。支持 ^ $ . + ? /> /< () | []command results 命令结果每一条命令有俩个结果:一个退出值和一个字符串。退出值标志着命令是否正确执行,字符串给出附加信息。有效的返回制定议在`tcl.h', 如下:tcl_ok命令正确执行,字符串给出了命令的返回值。tcl_error 表示有一个错误发生,字符串给出了错误的描述。全局变量 errorinfo 包含了人类可读的错误描述,全局变量errorcode 机器使用的错误信息。 tcl_return 表示 return 命令被调用,当前的命令(通常是一个函数)必须立刻返回,字符串包含了返回值。tcl_break 表示break已经被调用,最近的巡环必须立刻返回并跳出。字符串应该是空的。tcl_continue 表示continue已经被调用,最近的巡环必须立刻返回不跳出。字符串应该是空的。tcl编程者一般需要关心退出值。当tcl解释器发现错误发生后会立刻停止执行。procedures 函数tcl 允许你通过proc命令来扩充命令(定义新的命令),定义之后可以向其它的内建命令一样使用。例如:proc pf {str} { puts $str}pf "hello world"这里有一个初学者不注意的地方,上述的定义一定要写成那样子。而不能向下面那样写:proc pf {str} { puts $str}因为proc实际上也只不过是一条命令,是一换行符或分号来结束的,用集群参数来传递函数体。proc的定义如下:proc name args tclcommandvariables: scalars and arrays 变量:标量和向量(即数组)向量就是数组,而标量是没有下表的变量。我们用c来类比:int i; // i 是标量int j[10]; // j 是向量变量不需要定义,使用的时候会自动的被创建。tcl支持两种变量:标量和向量举个例子来说明吧,set i 100set j(0) 10set k(1,3) 20i是标量,j是向量。引用的时候:$i$j(0)$k(1,3)
转载地址:http://adedi.baihongyu.com/