Provided by: tcl8.5-doc_8.5.19-1_all bug

NAME

       upvar - Create link to variable in a different stack frame

SYNOPSIS

       upvar ?level? otherVar myVar ?otherVar myVar ...?
________________________________________________________________________________________________________________

DESCRIPTION

       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.  Level may have any of the forms  permitted  for  the
       uplevel  command,  and  may  be omitted if the first letter of the first otherVar is not # or a digit (it
       defaults to 1).  For each otherVar argument, upvar makes the variable by that name in the procedure frame
       given by level (or at global level, if level is #0) accessible in the current procedure by the name given
       in the corresponding myVar argument.  The variable named by otherVar need not exist at the  time  of  the
       call;  it will be created the first time myVar is referenced, just like an ordinary variable.  There must
       not exist a variable by the name myVar at the time upvar is invoked.  MyVar is always treated as the name
       of  a variable, not an array element.  An error is returned if the name looks like an array element, such
       as a(b).  OtherVar may refer to a scalar variable, an array, or an array element.  Upvar returns an empty
       string.

       The upvar 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:
              proc add2 name {
                 upvar $name x
                 set x [expr {$x + 2}]
              }
       If  add2  is  invoked  with  an  argument giving the name of a variable, it adds two to the value of that
       variable.  Although add2 could have been implemented using uplevel  instead  of  upvar,  upvar  makes  it
       simpler for add2 to access the variable in the caller's procedure frame.

       namespace  eval 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  namespace  eval  command
       counts  as  another  call  level for uplevel and upvar commands.  For example, info level 1 will return a
       list describing a command that is either the outermost procedure call or  the  outermost  namespace  eval
       command.   Also,  uplevel  #0  evaluates  a  script  at  top-level in the outermost namespace (the global
       namespace).

       If an upvar variable is unset (e.g. x in add2 above), the unset 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 upvar command.

TRACES AND UPVAR

       Upvar  interacts with traces in a straightforward but possibly unexpected manner.  If a variable trace is
       defined on otherVar, that trace will be  triggered  by  actions  involving  myVar.   However,  the  trace
       procedure  will  be  passed the name of myVar, rather than the name of otherVar.  Thus, the output of the
       following code will be “localVar” rather than “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

       If otherVar refers to an element of an array, then variable traces set for the entire array will  not  be
       invoked  when  myVar  is  accessed  (but  traces  on  the  particular element will still be invoked).  In
       particular, if the array is env, then changes made to myVar will not be passed to subprocesses correctly.

EXAMPLE

       A decr command that works like incr except it subtracts the value from the variable instead of adding it:
              proc decr {varName {decrement 1}} {
                  upvar 1 $varName var
                  incr var [expr {-$decrement}]
              }

SEE ALSO

       global(3tcl), namespace(3tcl), uplevel(3tcl), variable(3tcl)

KEYWORDS

       context, frame, global, level, namespace, procedure, variable

Tcl                                                                                                  upvar(3tcl)