Call by Name Using upvar

   

Practical Programming in Tcl & Tk, Third Edition
By Brent B. Welch

Table of Contents
Chapter 7.  Procedures and Scope


Call by Name Using upvar

Use the upvar command when you need to pass the name of a variable, as opposed to its value, into a procedure. The upvar command associates a local variable with a variable in a scope up the Tcl call stack. The syntax of the upvar command is:

 upvar ?level? varName localvar 

The level argument is optional, and it defaults to 1, which means one level up the Tcl call stack. You can specify some other number of frames to go up, or you can specify an absolute frame number with a #number syntax. Level #0 is the global scope, so the global foo command is equivalent to:

 upvar #0 foo foo 

The variable in the uplevel stack frame can be either a scalar variable, an array element, or an array name. In the first two cases, the local variable is treated like a scalar variable. In the case of an array name, then the local variable is treated like an array. The use of upvar and arrays is discussed further in Chapter 8 on page 92. The following procedure uses upvar to print the value of a variable given its name.

Example 7-5 Print variable by name.
 proc PrintByName { varName } {    upvar 1 $varName var    puts stdout "$varName = $var" } 

You can use upvar to fix the incr command. One drawback of the built-in incr is that it raises an error if the variable does not exist. We can define a new version of incr that initializes the variable if it does not already exist:

Example 7-6 Improved incr procedure.
 proc incr { varName {amount 1}} {    upvar 1 $varName var    if {[info exists var]} {       set var [expr $var + $amount]    } else {       set var $amount    }    return $var } 

       
    Top
     



    Practical Programming in Tcl and Tk
    Practical Programming in Tcl and Tk (4th Edition)
    ISBN: 0130385603
    EAN: 2147483647
    Year: 1999
    Pages: 478

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net