| |
1.Proc
Proc procname arg body
1 % proc plus {a b} {expr {$a+$b}}
2 % plus 2 4
6
3 % proc fac {x} {
> if {$x < 1} {
> return 1
> }
> return [expr {$x *[fac [expr {$x-1}]]}]
> }
4 % fac 4
24
5 % fac 0
1
2.Global
Global x y
指定xy 为全局变量
6 % proc pv {} {
> global a b
> puts "a is $a,b is $b"
> }
7 % set a 10
10
8 % set b 20
20
9 % pv
a is 10,b is 20
如果参数的子列表含义两个元素,第一个参数为参数名,第二个元素为其默认值
10 % proc inc {value {increment 1}} {
> expr $value+$increment
> }
11 % inc 42 3
45
12 % inc 42
43
13 %
含义默认值的参数,必须放在过程的参数列表的尾部。
3.Upvar
Tcl不支持指针和引用类型,但是可以模拟出引用的行为
13 % set x "the value of xx"
the value of xx
14 % set y x
x
15 % set $y
the value of xx
16 % puts $y
x
17 % puts $$y
$x
Tcl将$y替换为他的字符串值x,然后执行set,吧他的参数解析成一个变量的名称
返回存放在该变量中的值
有了这个概念,tcl的upvar命令,就可以实现与传引用调用相同的行为
Upvar名利提供方位当前过程的上下文范围之外的变量的通用机制。可以用于方位全局变量,命名空间变量以及其他活动中的过程内的局部变量。他更常见的使用则是模拟传引用调用的行为,这对数组特别有用,如果a是一个数组,就不能像myproc $a这样把它传给myproc
但是可以吧数组的名字传给过程,如myproc a,然而使用upvar命令在过程中访问数组的元素。
20 % proc pa {name} {
> upvar $name a
> foreach el [lsort [array names a]] {
> puts "$el=$a($el)"
> }
> }
21 % set info(age) 37
37
22 % set info(pos) "vice president"
vice president
23 % pa info
age=37
pos=vice president
Upvar命令使得过程可以通过变量a访问这个数组,upvar的第一个参数是过程的调用环境课件的变量,这可以是一个全局变量,也可以是一个命名空间变量,第二个参数是一个局部比那辆的名称,upvar把对局部变量a 的返回重定向到调用环境中名为name的变量。
Upvar命令的第一个变量名默认指向当前过程的调用者的上下文环境,不过他也可以访问调用堆栈中任意层级的变量,包括全局层级。
Upvar #0 other x
使用全局变量other可以通过局部变量x访问(参数#0指明other应该解释为全局变量)
Upvar 2 other x
使得当前过程的调用者的调用者的上下文环境中的other可以通过局部变量x访问(2指明other应该在比当前调用堆栈高2个层级的环境中)。层级0(与#0不同)表示的是当前上下文环境。
4.Uplevel
uplevel命令像是eval和upvar的结合。他把参数作为脚本处理,正如eval,但处理脚本的变量上下文环境却不在调用堆栈层级中,正如upvar。使用uplevel可以用tcl过程定义新的控制结构。
24 % proc dp {varname first last body} {
> upvar $varname v
> for {set v $first} {$v<= $last} {incr v} {
> uplevel $body
> }
> }
25 % set squares {}
26 % do i 1 5 {
> lappend squares [expr $i*#i]
> }
invalid command name "do"
27 % dp i 1 5 {
> lappend squares [expr $i*$i]
> }
28 % set squares
1 4 9 16 25
29 % set i
6