Tcl tick 的构成在下面的清单中,将会发现第一个很常见的示例程序,它是用 Tcl 实现的。这是一个完整的脚本:第一行命令调用 tclsh 环境,第二行命令执行实际工作。用您所选择的文本编辑器创建该脚本,输入 chmod +x hello.tcl 使之成为可执行文件,然后执行它以测试您这件“作品”。
1
2
3
4
5
6
| ~/tcltk$ cat hello.tcl
#!/usr/bin/tclsh
puts stdout {Hello, World!}
~/tcltk$ ./hello.tcl
Hello, World!
|
Tcl 和 Tk 是解释型的、可扩展脚本语言。与 BSD 许可证十分相似,该许可证允许在任何情况下自由使用该软件,只要在所有副本中保留该版权并且在任何分发中一字不差地传递通告。这个许可证条款使 Tcl/Tk 成为自由软件。
Tcl/Tk 是一种解释型环境。可以通过添加预编译的 C 函数来扩展 Tcl 解释器,可从 Tcl 环境内部调用 Tcl 解释器。可以为特定目的或一般的以及广泛使用的而定制这些扩展。我们将在教程的后面看一些扩展并着重看一下第一个扩展 ― 非常流行的 Expect。
在接下来的几屏中,将回顾 Tcl 语言的一些主要特性,从元字符和全局变量到运算符、数学函数以及核心命令。毕竟,这些命令使 Tcl/Tk 成为有特色的,逐步发展的语言。请记住,在本教程中没有篇幅涉及每条命令。这里只突出一部分,以后您可以更进一步了解 Tcl/Tk。
Tcl 元字符1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| #!/usr/bin/tclsh
# filename hello2.tcl
# This program code shows
# metacharacter usage
puts stdout "Hello, World! \a"
puts stdout {Hello, World! \a}
set Pints 6
set Days 7
puts stdout "The answer to the \
universe is [eval $Pints * $Days]!\n"
***
~/tcltk$ ./hello2.tcl
Hello, World!
Hello, World! \a
The answer to everything is 42!
|
元字符是在 Tcl/Tk 环境的上下文中有特殊含意的字符或字符对,它们包括分组语句、封装字符串、终止语句以及其它,如下表所示。左边列出的代码中演示了一些元字符。要注意的一个特殊特性是,当使用花括号(防止替代和扩展)代替双引号时,输出中的差异。
字符用作#注释; 或newline语句分隔符Name变量(区分大小写)Name(idx)数组变量Name(j,k,l...)多维数组"string"带替换的引用{string}不带替换的引用[string]命令替换\char反斜杠替代\行继续(在行尾)
Tcl 全局变量和反斜杠替代1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| #!/usr/bin/tclsh
#
# Demonstrate global variables
# and backslash substitution
if {$argc >= 1} {
set N 1
foreach Arg $argv {
puts stdout "$N: $Arg\n"
set N [expr $N + 1]
if {$Arg == "ring"} {
puts stdout "\a"
}
}
} else {
puts stdout "$argv0 on \
X Display $env(DISPLAY)\n"
}
***
~/tcltk$ ./hello3.tcl
./hello3.tcl on X Display :0.0
~/tcltk$ ./hello3.tcl ring
1: ring
|
当 Tcl/Tk 脚本开始运行时,存在几个全局变量(如果在当前环境中为非空,则是预先定义的)。这些变量允许如下对操作系统进行访问:argc 是对脚本自变量的计数,而不是对调用的名称进行计数。 argv 是自变量的列表(不是数组)。argv0 是调用的文件名(可以是符号链接)。env 是根据当前外壳的环境变量名建立下标的数组。errorCode 存储有关最近的 Tcl 错误信息,errorInfo 包含对这同一个错误事件的堆栈跟踪。该列表还有另外 12 个 tcl_xxx 变量,从 tcl_interactive 到 tcl_version。可以在 Tcl/Tk in a Nutshell 中找到好的总结,(有关更多信息,请参阅本教程末尾的“参考资料”)。
在左边的样本代码中,使用了其中几个变量以及(又一次)使用了一些反斜杠引用的字符(\n 和 \a)。 \char 允许替代非打印 ASCII 字符。这对于 UNIX 下的许多脚本语言和外壳环境都是常见的。如表中说明的那样,对于没有定义替代的反斜杠引用的字符只被简单地回送到输出。
\字符替代\a响铃\b退格\f换页\n 或 \newline新行\r回车\t水平制表\v垂直制表\space ("\ ")空格\ddd八进制值\xddd...十六进制值\c回显‘c’\\反斜杠
Tcl 运算符和数学函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| ~/tcltk$ cat maths.tcl
#!/usr/bin/tclsh
#
# Demonstrate operators and
# math functions
set PI [expr 2 * asin(1.0)]
if {$argc == 3} {
set X [lindex $argv 0]
set Y [lindex $argv 1]
set Rad [lindex $argv 2]
set Dist [expr sqrt(($X*$X)+($Y*$Y))]
set Cir [expr 2*$PI*$Rad]
set Area [expr $PI*$Rad*$Rad]
puts stdout "Distance = $Dist"
puts stdout "Circumference = $Cir"
puts stdout "Area = $Area"
} else {
puts stdout "Wrong argument count!"
puts stdout "Needs X, Y, and Radius"
}
********
~/tcltk$ ./maths.tcl 3 4 5
Distance = 5.0
Circumference = 31.4159265359
Area = 78.5398163397
|
Tcl 支持一组标准的运算符和数学函数。这些运算符包括算术、位和逻辑运算符,可以通过 expr 命令使用常规的运算符优先次序规则进行求值。另外,考虑到 Tcl 的实质是面向字符串的脚本语言,所以对一些数学函数进行了合理的补充:
- 三角函数包括 cos(x)、acos(x)、cosh(x)、sin(x)、asin(x)、sinh(x)、tan(x)、atan(x)、atan2(y, x)、tanh(x) 和 hypot(x, y)。与这些函数相关的单位是弧度。
- Log 函数是 exp(x)、log(x) 和 log10(x)。
- 算术函数是 ceil(x)、floor(x)、fmod(x, y)、pow(x, y)、abs(x)、int(x)、double(x) 和 round(x)。
- rand() 和 srand(x) 是处理随机数的函数。
左边这个示例使用了其中一些运算符和函数来计算指定点到原点之间的距离,并返回给定半径的圆的周长和面积。另外,在这个示例中,使用列表下标(lindex)命令来访问 $argv 的个别元素。
Tcl 中的循环和分支1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| ...
#
# parse command line switches
set Optimize 0
set Verbose 0
foreach Arg $argv {
switch -glob -- $Arg {
-o* {set Optimize 1}
-v* {set Verbose 1}
default {
error "Unknown $Arg"
}
}
}
set LineCount 0
while {[gets stdin Line] >= 0} {
# to confuse Vanna White...
Remove_Vowels $Line \
$Optimize $Verbose
incr LineCount
}
return LineCount
...
|
Tcl 中的循环命令是 while、for 和 foreach。条件(转移)命令是if/then/else/elsif 和 switch。上述命令的限定语句是 break、continue、return和 error。最后,catch 命令提供了错误处理能力。
if/then/else/elsif 已在前面几屏中演示过。在正式语法中会用到 then,但通常会省略掉它。
在左边这个示例中,foreach 结构给 switch 命令提供命令行自变量。当处理自变量时(注意:不正确的输入会终止脚本,因为还没有实现处理错误的 catch),while 循环通过为每一行调用过程并同时对行计数器加 1 来处理输入。代码段结束时,返回处理的行数。
Tcl 字符串和模式匹配1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| ~/tcltk$ tclsh
% set Phrase "hello, world!"
hello, world!
% string toupper $Phrase
HELLO, WORLD!
% string totitle $Phrase
Hello, world!
% string match ello $Phrase
0
% string match *ello* $Phrase
1
% string length $Phrase
14
% append Phrase "Nice day, eh?"
hello, world!
Nice day, eh?
% string toupper $Phrase
HELLO, WORLD!
NICE DAY, EH?
% string wordend $Phrase 7
12
|
字符串是 Tcl 中的基本数据类型。string 命令实际上是一组命令,这些命令都是属于 string 的。在使用中,正如在左边的示例中所看到,string 读取的方式非常象来自 OOP 编程特定对象方法的应用程序。
表示信息的 string 命令是 length 和 bytelength(可以有所不同,这取决于字符集)。返回布尔值(1 或 0)的比较是 compare、equal 和 match。这里的模式匹配是由“文件名替换”(简单类型的匹配通常与外壳操作相关)完成。还可以通过独特的 regex 和 regsub 命令来使用“高级正规表达式”。
在 Tcl 中执行 index、last、first、wordend 和 wordstart 命令可以实现下标功能。字符串修改是由 tolower、toupper、totitle、trim、trimleft、trimright、replace 和 map 来处理的。后者需要预先定义一个字符映射表。用 range 抽取子字符串,用 repeat 多次输出字符串。
可以使用 append 命令,将文本添加到现有变量中。通过使用与 C 语言的 printf 命令相同的样式和约定,format 命令可用来生成输出字符串。scan 对字符串进行解析并将值赋值给变量。最后,从 Tcl 8.0 开始,用 binary format 和 binary scan 命令添加了将二进制数据作为字符串处理的功能(因而能够处理空字符,而不会失败)。 |