Purpose: A place for code that isn't really [Advanced Tcl] and yet not [Beginning Tcl] either. DL ''such as...?'' ---- * [Creating Temporary Files] * [Making a Path Absolute] * [Writing Tcl scripts for eggdrop] * [Practical Introduction to Upvar and Uplevel] ---- [Category Tutorial] nomobaloney@hotmail.com/marsd wrote this and he's not proud. I had a lot of trouble with upvar and uplevel up till a year or so ago so I figured I'd give a short overview of what I've learned of dealing with them. I'll just use two basic proc's for this "tutorial": Number One:(upvar) proc pass {val {bdy "puts $LOCAL"} {lvl "#0"}} { upvar $lvl $val LOCAL eval $bdy } Description: A flexible proc that accepts various arguments: val = the upvar variable to work with. bdy = the commands to be executed..default is just to print to stdout the pointed variable. lvl = what stacklevel do we want to work with? Number two:(uplevel) proc putUp {cmd {lvl "#0"}} { uplevel $lvl "eval $cmd" } Description: A flexible proc that evaluates $cmd at the lvl pointed stack. Disclaimer: I've got some negative feedback for using uplevel this way. Using uplevel this way WILL affect your program differently than using uplevel {command}. The method "cmd" allows transparent use of local and global variables, the other {cmd} causes problems with local variable evaluation. Maybe an expert could discuss the evaluation issue. Notes on levels: The "lvl" default arg in both proc's refers to a "stack level", a reference to #0 means global, #1 is up one level, #2 up two. There is no converse. No downlevel. The examples given will work well enough for all stack levels. Just Jump in here: Try running this example in tkcon or tclsh after loading the above procs into them. set x 12 pass x putUp {puts $x} Well if you've worked with upvar and uplevel before you'll know that's what these commands do, and should probably be somewhere else ;) You should get 12 for each. Now we modify the values twice via both proc's: pass x {set LOCAL 3 ; puts $LOCAL ; putUp {set x 12}} puts $x putUp {set x 3 ; puts $x ; pass x {set LOCAL 12}} puts $x Break the command down and try it piece by piece if you don't follow the above. This one is simpler, unsetting x: pass x {unset LOCAL} set x 12 putUp {unset x} This one may be a little confusing: putUp {proc foo {{x} {puts $x ; pass x {set LOCAL 21} "#1"}}} rename foo "" This calls the pass proc from a "dynamically" created proc named foo, created at the global stack level by the putUp proc. pass resets a variable passed to foo in from the lower stack level inside foo. Control passes back and we destroy foo. A one shot wonder. This is the real power of tcl illustrated. The flexibility of the language is amazing. Finally: Be aware that the info commands are very helpful in dynamically creating and keeping straight your processes called at various levels. set x 12 pass x {puts "[info level], [info level 1]" ; set LOCAL 2} The command {info level} tells what stack level the calling process is coming from. With the additional {info level "level"} arg the interpreter looks for any operations at that stack level.