upvar 命令简化了传名调用(call-by-name)过程的实现并使它易于建立如同 Tcl 过程的新控制结构。例如,考虑下列过程:
proc add2 name {
upvar $name x
set x [expr $x+2]
}
调用 Add2
时加上给出一个变量名字的一个参数,它向这个变量的值加二。尽管
add2 可以使用 uplevel 替代 upvar
来实现,upvar 简便了 add2
访问在调用者过程桢中的变量。
namespace eval 是改变 Tcl 命令上下文的另一种方式(除了过程调用之外)。它向栈增加一个调用桢来表示名字空间上下文。这意味着每个 namespace eval 命令被视为给 uplevel 和 upvar 命令的另一个调用层次。例如,info level 1 将返回描述一个命令的列表,它要么是最外的过程要么是最外的 namespace eval 命令。还有,uplevel #0 在最外面的名字空间(全局名字空间)中的顶层求值一个脚本。
如果删除(unset)一个 upvar 变量(比如,上面的 add2 中的 x ),则 unset 操作影响它所连接到的变量,而不是 upvar 变量。除了退出在其中定义它的那个过程之外,没有方法删除一个 upvar 变量。但是,可以通过执行另一个 upvar 命令来为一个 upvar 变量重定目标(retarget)。
proc traceproc { name index op } {
puts $name
}
proc setByUpvar { name value } {
upvar $name localVar
set localVar $value
}
set originalVar 1
trace variable originalVar w traceproc
setByUpvar originalVar 2
}
如果 otherVar
引用一个数组的元素,则为整个数组设置的变量跟踪在 myVar
被访问的时候将不被调用(但在特定元素上的跟踪仍将被调用)。特别的,如果这个数组是
env,则对 myVar
的变动将不被正确的传递给子进程。
Copyright © 1993 The Regents of the University of California. Copyright © 1994-1997 Sun Microsystems, Inc. Copyright © 1995-1997 Roger E. Critchlow Jr.