我在理解在TCL中使用uplevel时遇到了一些问题。我正在阅读布伦特韦尔奇在TCL和Tk的实用编程,并且有一个我无法理解的高级例子。这是:
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]
}
有人可以向我解释一下吗?书中的解释对我没有多大帮助:(
答案 0 :(得分:7)
uplevel
命令在另一个范围内执行命令(或实际上是一个脚本),而不是当前过程的范围。特别是,在这种情况下,它是uplevel 1
,这意味着“在调用者中执行”。 (您也可以使用uplevel #0
在全局范围内执行,或者在其他地方执行,例如调用者的调用者uplevel 2
,但真的罕见。)
解释该行的其余部分:这里使用list
是一种构建无替换命令的方法,该命令由四个单词foreach
组成,args
的内容为{{ 1}}变量,valueList
变量的内容和break
(实际上不需要在括号中)。这会将valueList
前面的值分配给args
中列出的每个变量,然后停止,它将在调用者的上下文中执行。
总的来说,这个过程就像8.5中的内置lassign
一样(假设一个非空的输入列表和变量列表),除了因为范围和类似事件之间的交换的复杂性以外更慢。 / p>
答案 1 :(得分:4)
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"
这里最里面的方法a将在0级和b级,c级在2级,主程序将在3级,所以在proc a中如果我改变了level的值那么我可以改变变量的值任何过程的x都是a,b,c或来自方法的主要过程" a"本身。 尝试将级别更改为3,2,1,0并查看魔法输入。