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.