从tcl的tutorial中对upvar的说明如下,一开始真是看的云里雾里,终于在多次试验之后,终于知道了这个玩意该怎么使用了。
The upvar
command is similar. It "ties" the name of a variable in the current scope to a variable in a different scope. This is commonly used to simulate pass-by-reference to procs.
You might also encounter the variable
command in others' Tcl code. It is part of the namespace system and is discussed in detail in that chapter.
Normally, Tcl uses a type of "garbage collection" called reference counting in order to automatically clean up variables when they are not used anymore, such as when they go "out of scope" at the end of a procedure, so that you don't have to keep track of them yourself. It is also possible to explicitly unset them with the aptly named unset
command.
The syntax for upvar
is:
upvar
?level?
otherVar1
myVar1
?otherVar2
myVar2?
...
?otherVarN
myVarN?
The upvar
command causes myVar1
to become a reference to otherVar1
, and myVar2
to become a reference to otherVar2
, etc. The otherVar
variable is declared to be at level
relative to the current procedure. By default level
is 1, the next level up.
If a number is used for the level
, then level references that many levels up the stack from the current level.
从tutorial中我们可以看到,upvar level otherVar myVar,这句语句的意思就是将从第几个level中,将otherVar的索引赋值给myVar。注意:这个otherVar不是存在本层,而是存在与由level定义的层中(默认level=1),而这个myVar就是本层使用的变量名。这样就可以实现在本层调用别的层定义的变量了。实现global全局调用。
tutorial不建议用户使用太多的global 变量,如果必须使用,那么请再好好看看程序设计,是否能够减少global变量的调用。
举例说明:
【1】 level =1
>>>>>>>如何使用level>>>>>
proc ADD {a b} {
upvar 1 c factor
#将上一层(level = 1, -> King)定义的c传给factor
puts "factor = $factor"
return [expr {($a+$b) * $factor}]
#实现(a+b)*factor
}
proc King {a b c} {
set e [ADD $a $b]
#将a+b赋值给e
puts "e = $e"
return $e
#返回两倍的e
}
set h [King 1 2 2]
puts "h = $h"
puts "c = $c"
#>>>打印结果>>>
#h = 6
【2】level = 2
set c 2
proc ADD {a b} {
upvar 2 c factor
#将上两层(level = 2, -> set c 2)定义的c传给factor
return [expr {($a+$b) * $factor}]
#实现(a+b)*factor
}
proc King {a b} {
set e [ADD $a $b]
#将a+b赋值给e
return $e
#返回两倍的e
}
以上两种方式都可以实现相同的目的,区别就在与这个变量c处在第几层。
以上例子介绍到了proc的套用,可与C语言的局部函数和全局函数类比。
如这里有两个proc,分别是proc ADD 和proc King
在proc King中需要调用proc ADD,使用方法是:set a [ADD $a $b] -> 这里声明一个变量a,将proc ADD计算得到的值赋值给a。注意这里proc ADD {a b}使用的两个arguments,是由proc King {a b} 传进来的,因此需要取其值$a, $b,而不是用a,b.