Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot understand uplevel command in TCL

Tags:

tcl

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 :(

like image 429
coffeeak Avatar asked Jul 18 '12 03:07

coffeeak


People also ask

What does UPLevel do in TCL?

Uplevel returns the result of that evaluation. If level is an integer then it gives a distance (up the procedure calling stack) to move before executing the command. If level consists of # followed by a number then the number gives an absolute level number. If level is omitted then it defaults to 1.

What does UPLevel do?

UPLevel is a medium-sized business with multiple contact centres providing customer care, financial care, and business process outsourcing solutions in North America and beyond.


2 Answers

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.

like image 157
Donal Fellows Avatar answered Oct 30 '22 14:10

Donal Fellows


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.

like image 21
abcdefgh Avatar answered Oct 30 '22 15:10

abcdefgh