目录
过程定义和返回值
TCL 支持过程的定义和调用,在 TCL 中,过程可以看作是用 TCL 脚本实现的命令,效果与 TCL 的固有命令相似。我们可以在任何时候使用 proc 命令定义自己的过程,TCL 中的过程类似于 C 中的函数。
TCL 中过程是由 proc 命令产生的:
proc add {x y } {expr $x+$y}
proc 命令的第一个参数是你要定义的过程的名字,第二个参数是过程的参数列表,参数之间用 空格隔开,第三个参数是一个 TCL 脚本,代表过程体。 proc 生成一个新的命令,可以象固有 命令一样调用:
add 1 2
输出:3
在定义过程时,你可以利用 return 命令在任何地方返回你想要的值。 return 命令迅速中断过 程,并把它的参数作为过程的结果。例如:
proc abs {x} {
if {$x >= 0} { return $x }
return [expr -$x]
}
过程的返回值是过程体中最后执行的那条命令的返回值。
局部变量和全局变量
对于在过程中定义的变量,因为它们只能在过程中被访问,并且当过程退出时会被自动删除,所 以称为局部变量;在所有过程之外定义的变量我们称之为全局变量。TCL 中,局部变量和全局 变量可以同名,两者的作用域的交集为空:局部变量的作用域是它所在的过程的内部;全局变量 的作用域则不包括所有过程的内部。这一点和 C 语言有很大的不同
如果我们想在过程内部引用一个全局变量的值,可以使用 global 命令。例如:
set a 4
输出:4
proc sample { x } {
global a
incr a
return [expr $a+$x]
}
sample 3
输出:8
set a
输出:5
全局变量 a 在过程中被访问。在过程中对 a 的改变会直接反映到全局上。如果去掉语句 global a, TCL 会出错,因为它不认识变量 a。
缺省参数和可变个数参数
TCL 还提供三种特殊的参数形式:
首先,你可以定义一个没有参数的过程,例如:
proc add {} { expr 2+3}
其次,可以定义具有缺省参数值的过程,我们可以为过程的部分或全部参数提供缺省值,如果调 用过程时未提供那些参数的值,那么过程会自动使用缺省值赋给相应的参数。和 C\C++中具有 缺省参数值的函数一样,有缺省值的参数只能位于参数列表的后部,即在第一个具有缺省值的参 数后面的所有参数,都只能是具有缺省值的参数。
例如:
proc add {val1 {val2 2} {val3 3}}{
expr $val1+$val2+$val3
}
则:
add 1 //值为 6
add 2 20 //值为 25
add 4 5 6 //值为 15
另外,TCL 的过程定义还支持可变个数的参数,如果过程的最后一个参数是 args, 那么就表示 这个过程支持可变个数的参 饔谩5饔檬?位于 args 以前的参数象普通参数一样处理,但任何 附加的参数都需要在过程体中作特殊处理,过程的局部变量 args 将会被设置为一个列表,其元 素就是所有附加的变量。如果没有附加的变量,args 就设置成一个空串,下面是一个例子:
proc add { val1 args } {
set sum $val1
foreach i $args {
incr sum $i
}
return $sum
}
则:
add 2 //值为 2
add 2 3 4 5 6 //值为 20
引用:upcar
命令语法:upvar ?level? otherVar myVar ?otherVar myVar ...?
upvar 命令使得用户可以在过程中对全局变量或其他过程中的局部变量进行访问。 upvar 命令 的第一个参数 otherVar 是我们希望以引用方式访问的参数的名字,第二个参数 myVar 是这个 过程中的局部变量的名字,一旦使用了 upvar 命令把 otherVar 和 myVar 绑定,那么在过程 中对局部变量 myVar 的读写就相当于对这个过程的调用者中 otherVar 所代表的局部变量的 读写。下面是一个例子:
% proc temp { arg } {
upvar $arg b
set b [expr $b+2]
}
% proc myexp { var } {
set a 4
temp a
return [expr $var+$a]
}
则:
% myexp 7
输出:13
这个例子中,upvar 把$arg(实际上是过程 myexp 中的变量 a)和过程 temp 中的变量 b 绑定, 对 b 的读写就相当于对 a 的读写。
upvar 命令语法中的 level 参数表示:调用 upvar 命令的过程相对于我们希望引用的变量 myVar 在调用栈中相对位置。例如:
upvar 2 other x
这个命令使得当前过程的调用者的调用者中的变量 other,可以在当前过程中利用 x 访问。缺省 情况下,level 的值为 1,即当前过程(上例中的 temp)的调用者(上例中的 myexp)中的变量(上 例中 myexp 的 a)可以在当前过程中利用局部变量(上例中 temp 的 b)访问。
如果要访问全局变量可以这样写:
upvar #0 other x
那么,不管当前过程处于调用栈中的什么位置,都可以在当前过程中利用 x 访问全局变量 other。