无法理解TCL中的uplevel命令
我在理解uplevel在TCL中的使用时遇到了一些问题。我正在阅读布伦特·韦尔奇(Brent Welch)在TCL和Tk中的实用编程,在uplevel中有一个我无法理解的例子。这是:无法理解TCL中的uplevel命令,tcl,Tcl,我在理解uplevel在TCL中的使用时遇到了一些问题。我正在阅读布伦特·韦尔奇(Brent Welch)在TCL和Tk中的实用编程,在uplevel中有一个我无法理解的例子。这是: proc lassign {valueList args} { if {[llength $args] == 0} { error "wrong # args:lassign list varname ?varname...?" } if {[llength $valueList] == 0}
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]
}
谁能给我解释一下吗?这本书中的解释对我的帮助还不够:(uplevel命令在当前过程之外的另一个范围内执行命令(或者实际上是脚本)。特别是,在这种情况下,它是
uplevel 1
,意思是“在调用者中执行”。(您也可以使用uplevel#0
在全局范围内执行,也可以使用uplevel 2
在其他地方执行,例如调用方的调用方,但这种情况非常罕见。)
解释该行的其余部分:这里使用list
是一种构造无替换命令的方法,该命令由四个字组成,foreach
,变量args
的内容,valueList
变量的内容,以及break
(实际上不需要放在大括号中)。这将从valueList
的前面为args
中列出的每个变量分配一个值,然后停止,并将在调用方的上下文中执行此操作
总的来说,该过程的工作原理与8.5中内置的lassign
类似(假设输入列表和变量列表为非空),但由于在作用域和类似对象之间交换的复杂性,速度较慢
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将在级别2中,c将在级别3中,因此在过程a中,如果我更改级别的值,那么我可以更改任何过程的变量x的值,无论是方法“a”本身的变量a、b、c还是主过程。
尝试将level更改为3,2,1,0,然后查看神奇的putput。在8.6中,我们设法找到了
uplevel#1
与协同程序的用法。这被认为是该特定形式有史以来的第一次实际使用,尽管它已经合法了几十年。语法描述如下:“如果级别由#后跟一个数字组成,则该数字给出一个绝对级别数字。”@DonalFellows不tailcall
顶部coroutine
堆栈。