1 | '\" |
---|
2 | '\" Copyright (c) 1993 The Regents of the University of California. |
---|
3 | '\" Copyright (c) 1994-1997 Sun Microsystems, Inc. |
---|
4 | '\" |
---|
5 | '\" See the file "license.terms" for information on usage and redistribution |
---|
6 | '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
---|
7 | '\" |
---|
8 | '\" RCS: @(#) $Id: upvar.n,v 1.16 2007/12/13 15:22:33 dgp Exp $ |
---|
9 | '\" |
---|
10 | .so man.macros |
---|
11 | .TH upvar n "" Tcl "Tcl Built-In Commands" |
---|
12 | .BS |
---|
13 | '\" Note: do not modify the .SH NAME line immediately below! |
---|
14 | .SH NAME |
---|
15 | upvar \- Create link to variable in a different stack frame |
---|
16 | .SH SYNOPSIS |
---|
17 | \fBupvar \fR?\fIlevel\fR? \fIotherVar myVar \fR?\fIotherVar myVar \fR...? |
---|
18 | .BE |
---|
19 | |
---|
20 | .SH DESCRIPTION |
---|
21 | .PP |
---|
22 | This command arranges for one or more local variables in the current |
---|
23 | procedure to refer to variables in an enclosing procedure call or |
---|
24 | to global variables. |
---|
25 | \fILevel\fR may have any of the forms permitted for the \fBuplevel\fR |
---|
26 | command, and may be omitted if the first letter of the first \fIotherVar\fR |
---|
27 | is not \fB#\fR or a digit (it defaults to \fB1\fR). |
---|
28 | For each \fIotherVar\fR argument, \fBupvar\fR makes the variable |
---|
29 | by that name in the procedure frame given by \fIlevel\fR (or at |
---|
30 | global level, if \fIlevel\fR is \fB#0\fR) accessible |
---|
31 | in the current procedure by the name given in the corresponding |
---|
32 | \fImyVar\fR argument. |
---|
33 | The variable named by \fIotherVar\fR need not exist at the time of the |
---|
34 | call; it will be created the first time \fImyVar\fR is referenced, just like |
---|
35 | an ordinary variable. There must not exist a variable by the |
---|
36 | name \fImyVar\fR at the time \fBupvar\fR is invoked. |
---|
37 | \fIMyVar\fR is always treated as the name of a variable, not an |
---|
38 | array element. An error is returned if the name looks like an array element, |
---|
39 | such as \fBa(b)\fR. |
---|
40 | \fIOtherVar\fR may refer to a scalar variable, an array, |
---|
41 | or an array element. |
---|
42 | \fBUpvar\fR returns an empty string. |
---|
43 | .PP |
---|
44 | The \fBupvar\fR command simplifies the implementation of call-by-name |
---|
45 | procedure calling and also makes it easier to build new control constructs |
---|
46 | as Tcl procedures. |
---|
47 | For example, consider the following procedure: |
---|
48 | .CS |
---|
49 | proc \fIadd2\fR name { |
---|
50 | \fBupvar\fR $name x |
---|
51 | set x [expr {$x + 2}] |
---|
52 | } |
---|
53 | .CE |
---|
54 | If \fIadd2\fR is invoked with an argument giving the name of a variable, |
---|
55 | it adds two to the value of that variable. |
---|
56 | Although \fIadd2\fR could have been implemented using \fBuplevel\fR |
---|
57 | instead of \fBupvar\fR, \fBupvar\fR makes it simpler for \fBadd2\fR |
---|
58 | to access the variable in the caller's procedure frame. |
---|
59 | .PP |
---|
60 | \fBnamespace eval\fR is another way (besides procedure calls) |
---|
61 | that the Tcl naming context can change. |
---|
62 | It adds a call frame to the stack to represent the namespace context. |
---|
63 | This means each \fBnamespace eval\fR command |
---|
64 | counts as another call level for \fBuplevel\fR and \fBupvar\fR commands. |
---|
65 | For example, \fBinfo level 1\fR will return a list |
---|
66 | describing a command that is either |
---|
67 | the outermost procedure call or the outermost \fBnamespace eval\fR command. |
---|
68 | Also, \fBuplevel #0\fR evaluates a script |
---|
69 | at top-level in the outermost namespace (the global namespace). |
---|
70 | .PP |
---|
71 | If an upvar variable is unset (e.g. \fBx\fR in \fBadd2\fR above), the |
---|
72 | \fBunset\fR operation affects the variable it is linked to, not the |
---|
73 | upvar variable. There is no way to unset an upvar variable except |
---|
74 | by exiting the procedure in which it is defined. However, it is |
---|
75 | possible to retarget an upvar variable by executing another \fBupvar\fR |
---|
76 | command. |
---|
77 | .SH "TRACES AND UPVAR" |
---|
78 | .PP |
---|
79 | Upvar interacts with traces in a straightforward but possibly |
---|
80 | unexpected manner. If a variable trace is defined on \fIotherVar\fR, that |
---|
81 | trace will be triggered by actions involving \fImyVar\fR. However, |
---|
82 | the trace procedure will be passed the name of \fImyVar\fR, rather |
---|
83 | than the name of \fIotherVar\fR. Thus, the output of the following code |
---|
84 | will be |
---|
85 | .QW "\fIlocalVar\fR" |
---|
86 | rather than |
---|
87 | .QW "\fIoriginalVar\fR" : |
---|
88 | .CS |
---|
89 | proc \fItraceproc\fR { name index op } { |
---|
90 | puts $name |
---|
91 | } |
---|
92 | proc \fIsetByUpvar\fR { name value } { |
---|
93 | \fBupvar\fR $name localVar |
---|
94 | set localVar $value |
---|
95 | } |
---|
96 | set originalVar 1 |
---|
97 | trace variable originalVar w \fItraceproc\fR |
---|
98 | \fIsetByUpvar\fR originalVar 2 |
---|
99 | .CE |
---|
100 | .PP |
---|
101 | If \fIotherVar\fR refers to an element of an array, then variable |
---|
102 | traces set for the entire array will not be invoked when \fImyVar\fR |
---|
103 | is accessed (but traces on the particular element will still be |
---|
104 | invoked). In particular, if the array is \fBenv\fR, then changes |
---|
105 | made to \fImyVar\fR will not be passed to subprocesses correctly. |
---|
106 | .SH EXAMPLE |
---|
107 | A \fBdecr\fR command that works like \fBincr\fR except it subtracts |
---|
108 | the value from the variable instead of adding it: |
---|
109 | .CS |
---|
110 | proc decr {varName {decrement 1}} { |
---|
111 | \fBupvar\fR 1 $varName var |
---|
112 | incr var [expr {-$decrement}] |
---|
113 | } |
---|
114 | .CE |
---|
115 | |
---|
116 | .SH "SEE ALSO" |
---|
117 | global(n), namespace(n), uplevel(n), variable(n) |
---|
118 | |
---|
119 | .SH KEYWORDS |
---|
120 | context, frame, global, level, namespace, procedure, variable |
---|