Can anyone let me know the difference between upvar 0
and upvar 1
in TCL, how we can use in real time. Kindly, if someone explain with example, it makes me more clear.
The TCL language reference manual gives the following description for the command. upvar ?level? otherVar myVar ?otherVar myVar …? `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.
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. MyVar is always treated as the name of a variable, not an array element.
Also note that upvar is not about accessing global variables—this is usually achieved using the global and variable commands; instead, upvar is used to work with variables rather than values.
For example, consider the following procedure: Add2 is invoked with an argument giving the name of a variable, and 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.
When you are calling a bunch of procedures, you get a stack of stack frames. It's in the name. We might visualise this like so:
abc 123 456 bcd 321 456 cde 654 321
OK, so we've got abc
calling bcd
calling cde
. Simple.
The 0
and 1
in upvar
say how many levels to go up the stack when looking up the variable to link to. 1
means go up one level (i.e., to the caller of the current frame), say from cde
to bcd
in our example, 2
would go from cde
up to abc
and 3
all the way up to the global evaluation level where overall scripts and callbacks run. 0
is a special case of this; it means do the lookup in the current stack frame. There's also the ability to use indexing from the base of the stack by putting #
in front of the name, so #0
indicates the global frame, #1
the first thing it calls.
The most common use of upvar
is upvar 1
(and if you leave the level out, that's what it does). upvar 0
is only really used when you want to get a different (usually easier to work with) name for a variable. The next most common one is upvar #0
, though global
is a much more common shorthand there (which matches the unqualified parts of the name for your convenience). Other forms are rare; for example, upvar 2
is usually an indication of really confusing and tangled code, and hardly anyone ever used upvar #1
before Tcl 8.6's coroutines. I've never seen upvar 3
or upvar #2
in the wild (though computed level indicators are present in some object systems for Tcl).
upvar 1
— pass variable by name:proc mult-by {varName multiplier} {
upvar 1 $varName var
set var [expr {$var * $multiplier}]
}
set x 2
mult-by x 13
puts "x is now $x"
# x is now 26
upvar 0
— simplify variable name:proc remember {name contents} {
global my_memory_array
upvar 0 my_memory_array($name) var
if {[info exist var]} {
set var "\"$var $contents\""
} else {
set var "\"$name $contents\""
}
}
remember x 123
remember y 234
remember x 345
remember y 456
parray my_memory_array
# my_memory_array(x) = ""x 123" 345"
# my_memory_array(y) = ""y 234" 456"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With