Cannot understand uplevel command in TCL
Asked Answered
B

2

7

I am having some problems understanding the use of uplevel in TCL. I am reading Brent Welch's Practical programming in TCL and Tk and there is an example in uplevel that I cannot understand. Here it is:

proc lassign {valueList args} {
  if {[llength $args] == 0} {
    error "wrong # args:lassign list varname ?varname...?"
  }
  if {[llength $valueList] == 0} {
    #Ensure one trip through the foreach loop
    set valueList [List {}]
  }
  uplevel 1 [list foreach $args $valueList {break}]
  return [lrange $valueList [llength $args] end]
}

Can someone please explain it to me? The explanation in the book does not help me enough :(

Basalt answered 18/7, 2012 at 3:39 Comment(0)
R
7

The uplevel command executes a command (or in fact a script) in another scope than that of the current procedure. In particular, in this case it is uplevel 1 which means “execute in caller”. (You can also execute in the global scope with uplevel #0, or in other places too such as the caller's caller with uplevel 2 but that's really rare.)

Explaining the rest of that line: the use of the list here is as a way of constructing a substitution-free command, which consists of four words, foreach, the contents of the args variable, the contents of valueList variable, and break (which didn't actually need to be in braces). That will assign a value from the front of valueList to each variable listed in args, and then stop, and it will do so in the context of the caller.

Overall, the procedure works just like the built-in lassign in 8.5 (assuming a non-empty input list and variable list), except slower because of the complexity of swapping between scopes and things like that.

Radack answered 18/7, 2012 at 6:11 Comment(3)
In 8.6, we managed to find a use for uplevel #1 with coroutines. This was considered to be the first practical use ever for that particular form, even though it has been legal for decades.Radack
The #<number> syntax is described thus: "If level consists of # followed by a number then the number gives an absolute level number." tcl.tk/man/tcl8.5/TclCmd/uplevel.htmOshinski
@DonalFellows Don't tailcall the top coroutine stack.Nuss
G
5
proc a {} {
  set x a
  uplevel 3 {set x Hi}
  puts "x in a = $x"
}
proc b {} {
  set x b
  a
  puts "x in b = $x"
}
proc c {} {
  set x c
  b
  puts "x in c = $x"
}
set x main
c
puts "x in main == $x"

here the most inside method a will be in level 0 and b in level ,c in level 2 and main program will be in level 3 so in proc a if i change the value of level then i can change the value of variable x of any proc be it a,b,c or main proc from method "a" itself. try changing level to 3,2,1,0 and see the magic putput.

Gulf answered 27/2, 2015 at 10:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.