94 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <HTML><HEAD><TITLE>Built-In Commands - upvar manual page</TITLE></HEAD><BODY>
 | |
| <H3><A NAME="M2">NAME</A></H3>
 | |
| upvar - Create link to variable in a different stack frame
 | |
| <H3><A NAME="M3">SYNOPSIS</A></H3>
 | |
| <B>upvar </B>?<I>level</I>? <I>otherVar myVar </I>?<I>otherVar myVar </I>...?<BR>
 | |
| <H3><A NAME="M4">DESCRIPTION</A></H3>
 | |
| This command arranges for one or more local variables in the current
 | |
| procedure to refer to variables in an enclosing procedure call or
 | |
| to global variables.
 | |
| <I>Level</I> may have any of the forms permitted for the <B><A HREF="../TkCmd/uplevel.htm">uplevel</A></B>
 | |
| command, and may be omitted if the first letter of the first <I>otherVar</I>
 | |
| isn't <B>#</B> or a digit (it defaults to <B>1</B>).
 | |
| For each <I>otherVar</I> argument, <B>upvar</B> makes the variable
 | |
| by that name in the procedure frame given by <I>level</I> (or at
 | |
| global level, if <I>level</I> is <B>#0</B>) accessible
 | |
| in the current procedure by the name given in the corresponding
 | |
| <I>myVar</I> argument.
 | |
| The variable named by <I>otherVar</I> need not exist at the time of the
 | |
| call;  it will be created the first time <I>myVar</I> is referenced, just like
 | |
| an ordinary variable.  There must not exist a variable by the
 | |
| name <I>myVar</I> at the time <B>upvar</B> is invoked.
 | |
| <I>MyVar</I> is always treated as the name of a variable, not an
 | |
| array element.  Even if the name looks like an array element,
 | |
| such as <B>a(b)</B>, a regular variable is created.
 | |
| <I>OtherVar</I> may refer to a scalar variable, an array,
 | |
| or an array element.
 | |
| <B>Upvar</B> returns an empty string.
 | |
| <P>
 | |
| The <B>upvar</B> command simplifies the implementation of call-by-name
 | |
| procedure calling and also makes it easier to build new control constructs
 | |
| as Tcl procedures.
 | |
| For example, consider the following procedure:
 | |
| <PRE><B>proc add2 name {
 | |
| 	upvar $name x
 | |
| 	set x [expr $x+2]
 | |
| }</B></PRE>
 | |
| <B>Add2</B> is invoked with an argument giving the name of a variable,
 | |
| and it adds two to the value of that variable.
 | |
| Although <B>add2</B> could have been implemented using <B><A HREF="../TkCmd/uplevel.htm">uplevel</A></B>
 | |
| instead of <B>upvar</B>, <B>upvar</B> makes it simpler for <B>add2</B>
 | |
| to access the variable in the caller's procedure frame.
 | |
| <P>
 | |
| <B>namespace eval</B> is another way (besides procedure calls)
 | |
| that the Tcl naming context can change.
 | |
| It adds a call frame to the stack to represent the namespace context.
 | |
| This means each <B>namespace eval</B> command
 | |
| counts as another call level for <B><A HREF="../TkCmd/uplevel.htm">uplevel</A></B> and <B>upvar</B> commands.
 | |
| For example, <B>info level 1</B> will return a list
 | |
| describing a command that is either
 | |
| the outermost procedure call or the outermost <B>namespace eval</B> command.
 | |
| Also, <B>uplevel #0</B> evaluates a script
 | |
| at top-level in the outermost namespace (the global namespace).
 | |
| <P>
 | |
| If an upvar variable is unset (e.g. <B>x</B> in <B>add2</B> above), the
 | |
| <B><A HREF="../TkCmd/unset.htm">unset</A></B> operation affects the variable it is linked to, not the
 | |
| upvar variable.  There is no way to unset an upvar variable except
 | |
| by exiting the procedure in which it is defined.  However, it is
 | |
| possible to retarget an upvar variable by executing another <B>upvar</B>
 | |
| command.
 | |
| 
 | |
| <H3><A NAME="M5">Traces and upvar</A></H3>
 | |
| Upvar interacts with traces in a straightforward but possibly
 | |
| unexpected manner.  If a variable trace is defined on <I>otherVar</I>, that
 | |
| trace will be triggered by actions involving <I>myVar</I>.  However,
 | |
| the trace procedure will be passed the name of <I>myVar</I>, rather
 | |
| than the name of <I>otherVar</I>.  Thus, the output of the following code
 | |
| will be <B>localVar</B> rather than <B>originalVar</B>:
 | |
| <PRE><B>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
 | |
| }</B></PRE>
 | |
| If <I>otherVar</I> refers to an element of an array, then variable
 | |
| traces set for the entire array will not be invoked when <I>myVar</I>
 | |
| is accessed (but traces on the particular element will still be
 | |
| invoked).  In particular, if the array is <B>env</B>, then changes
 | |
| made to <I>myVar</I> will not be passed to subprocesses correctly.
 | |
| 
 | |
| <H3><A NAME="M6">SEE ALSO</A></H3>
 | |
| <B><A HREF="../TkCmd/global.htm">global</A></B>, <B><A HREF="../TkCmd/namespace.htm">namespace</A></B>, <B><A HREF="../TkCmd/uplevel.htm">uplevel</A></B>, <B><A HREF="../TkCmd/variable.htm">variable</A></B>
 | |
| <H3><A NAME="M7">KEYWORDS</A></H3>
 | |
| <A href="../Keywords/C.htm#context">context</A>, <A href="../Keywords/F.htm#frame">frame</A>, <A href="../Keywords/G.htm#global">global</A>, <A href="../Keywords/L.htm#level">level</A>, <A href="../Keywords/N.htm#namespace">namespace</A>, <A href="../Keywords/P.htm#procedure">procedure</A>, <A href="../Keywords/V.htm#variable">variable</A>
 | |
| <HR><PRE>
 | |
| <A HREF="../copyright.htm">Copyright</A> © 1993 The Regents of the University of California.
 | |
| <A HREF="../copyright.htm">Copyright</A> © 1994-1997 Sun Microsystems, Inc.
 | |
| <A HREF="../copyright.htm">Copyright</A> © 1995-1997 Roger E. Critchlow Jr.</PRE>
 | |
| </BODY></HTML>
 | 
