Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between upvar 0 and upvar 1 in TCL

Tags:

tcl

upvar

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.

like image 642
velpandian Avatar asked May 12 '15 11:05

velpandian


People also ask

What is The upvar command in Tcl?

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.

What is the difference between upvar and myVar?

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.

What is the difference between upvar and global variables?

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.

What is the difference between ADD2 and upvar in C++?

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.


1 Answers

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

Example of 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

Example of 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"
like image 56
Donal Fellows Avatar answered Oct 02 '22 18:10

Donal Fellows