upvar(3tcl)

NAME
upvar - 建立到在不同棧楨上的變數的連線

總覽 SYNOPSIS
upvar ?level? otherVar myVar ?otherVar myVar ...?

描述 DESCRIPTION

這個命令安排在當前過程中的一個或多個區域性變數去引用位於包圍它的過程呼叫中的變數或引用全域性變數。 Level 可以用 uplevel 命令允許的任何形式，並且如果第一個 otherVar 的第一個字母不是 # 或一個數字，則可以被省略(它預設為1)。對於每個 otherVar 引數，upvar 使由 level 給出的過程楨中(如果 level 是 #0 則在全域性層次)的叫這個名字的變數在當前過程中可以用由相應的 myVar 引數給出名字來訪問。在呼叫它的時候叫做 otherVar 的變數不需要存在；可以在第一次引用 myVar 時象普通變數那樣建立它。在呼叫 upvar 的時候一定不能存在一個叫 myVar 的變數。MyVar 總是被作為一個變數的名字來對待，而不是一個數組的元素。即使這個名字看起來象一個數組元素，比如 a(b)，仍建立一個正規的變數。OtherVar 可以引用一個標量變數，或一個數組元素。Upvar 返回一個空串。

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)。

Traces 和 upvar

upvar 以一種直接但可能不是預期的方式與 trace 互動。如果在 otherVar 上定義了一個變數跟蹤，涉及 myVar 的動作將觸發這個追蹤。但是，傳遞給跟蹤過程將是 myVar 的名字，而不是 otherVar 的名字。 所以，下列程式碼的輸出將是 localVar 而不是 originalVar:
    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 的變動將不被正確的傳遞給子程序。

參見 SEE ALSO
global(n), namespace(n), uplevel(n), variable(n)

關鍵字 KEYWORDS
context, frame, global, level, namespace, procedure, variable

[中文版維護人]
寒蟬退士

[中文版最新更新]
2001/11/21

《中國 Linux 論壇 man 手冊頁翻譯計劃》:
http://cmpp.linuxforum.net

跋
本頁面中文版由中文 man 手冊頁計劃提供。
中文 man 手冊頁計劃：https://github.com/man-pages-zh/manpages-zh