When you want to pass data INTO a proc in Tcl from a regular variable, you write the variable name with a $ in front of it in the code and the value is substituted. But this doesn't work if (a) you are passing an array (which cannot be expanded into a string or (b) you want to change the value in a variable, or pass a result back in it. So that's when you use
upvar.
It works like this. You pass in the NAME of the variable that you want to set / change, and then you use
upvar to say "the variable called
harry in this proc is the same as the varaible named in the
$text varaible passed in from the level above which is the same as the
mytext variable in that calling code." (Clearly, the names I have used are examples, and from this piece of code:
proc dress {text} {
upvar $text harry
set harry "<h1>$harry</h1>"
return [string length $harry]
}
set mytext "Hello World"
set sz [dress mytext]
puts "$sz $mytext"
Here's a sample that shows how this runs:
Dorothy-2:oct09 grahamellis$ tclsh tcl/dresser
20 <h1>Hello World</h1>Dorothy-2:oct09 grahamellis$
When you start looking at the built in commands in Tcl itself, you'll see how significant this is ... so many of them take parameters from which you omit the $ character and that's a sure sign that the
proc concerned does / will / might change the ingoing value. Examples that come to my mind include
foreach,
regsub,
regexp,
incr, and even
set!
The example above is on our web site
here. This is a subject that's not an obvious one when you first come to it, and there are all sorts of other
nasty things you can do with
upvar and
uplevel and so we spend a good time explaining and trying it out on both our
Tcl and Expect programming and our
Learning to program in Tcl courses.
Further examples:
here,
here (passing back an array), and
here.
Tcl offers further flexibility in proc (function) calls too - optional parameters are illustrated
here, calling procs with a variable number of parameters
here, using global variables (OK to use occasionally!)
here and you can even use
uplevel to run code in the level above - very specialised use, see example
here (written 2009-10-22)
Associated topics are indexed as below, or enter http://melksh.am/nnnn for individual articles
T208 - Tcl/Tk - Arrays and dicts [122] Passing arrays to procs in Tcl - (2004-11-18)
[779] The fragility of pancakes - and better structures - (2006-06-26)
[1282] Stringing together Tcl scripts - (2007-07-29)
[1283] Generating traffic for network testing - (2007-07-29)
[1405] Sorting in Tcl - lists and arrays - (2007-10-24)
[1427] Arrays in Tcl - a demonstration - (2007-11-10)
[1614] When an array is not an array - (2008-04-17)
[3192] Tcl - Some example of HOW TO in handling data files and formats - (2011-03-04)
[3415] User defined sorting and other uses of callbacks in Tcl and Tk - (2011-09-02)
[3582] Tcl collections - lists, dicts and array - (2012-01-16)
[3614] Tcl - dicts - a tutorial and examples - (2012-02-14)
[3638] Sorting dicts and arrays in Tcl - (2012-03-04)
T207 - Tcl/Tk - Procedures and Variable Scope [96] Variable Scope - (2004-10-22)
[308] Call by name v call by value - (2005-05-11)
[409] Functions and commands with dangerous names - (2005-08-11)
[775] Do not duplicate your code - (2006-06-23)
[1163] A better alternative to cutting and pasting code - (2007-04-26)
[1404] Tcl - global, upvar and uplevel. - (2007-10-24)
[1782] Calling procs in Tcl and how it compares to Perl - (2008-09-02)
[2476] Tcl - uplevel to run code at calling level - (2009-10-24)
[2520] Global and Enable - two misused words! - (2009-11-30)
[2929] Passing a variable number of parameters in to a function / method - (2010-08-20)
[3414] Passing back multiple results in Tcl - upvar and uplevel - (2011-09-01)
[3629] Sharing lots of values in Tcl without having lots of global declarations - (2012-02-28)
[4398] Accessing variables across subroutine boundaries - Perl, Python, Java and Tcl - (2015-01-18)
Some other Articles
Windows 7 and Open Source ProgrammingBeyond the PaleWhat are Tcl lists?Tcl - catching an error before your program crashesTcl - passing arrays and strings in and back out of procsMelksham Town - asleep or awake?Beauty in picturesTcl - a true interpretive, command based languagePython - how it saves on compile timeLuac - getting lua to start fast by precompiling