2012-07-18 198 views
6

我在理解TCL中uplevel的使用時遇到了一些問題。我正在閱讀布倫特韋爾奇在TCL和Tk上的實用編程,並且有一個我很難理解的高級示例。這裏是:無法理解TCL中的uplevel命令

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] 
} 

有人可以請解釋給我嗎?這本書中的解釋並不足以幫助我:(

回答

6

uplevel命令執行一個命令(或實際上是一個腳本)在另一個範圍內,而不是當前過程,特別是在這種情況下,它是uplevel 1,意思是「執行中的來電者」(你也可以執行在全球範圍內與uplevel #0,或在其他地方也如主叫方與uplevel 2主叫但是這真的罕見。)

解釋該行的其餘部分。在這裏使用list是作爲一種構建免替換命令的方式,其由四個字組成,即foreach,其內容args變量,valueList變量的內容和break(實際上並不需要使用大括號)。這將從valueList的前面向args中列出的每個變量賦值,然後停止,並且它將在調用者的上下文中執行此操作。

總體而言,該過程與8.5中的內置lassign(假設爲非空輸入列表和變量列表)相似,除了由於作用域之間交換的複雜性等因素而變慢之外。

+1

在8.6中,我們設法找到了帶有協程的'uplevel#1'的用法。這被認爲是該特定形式的第一個實際用途,即使它已經合法數十年。 – 2012-07-18 06:13:15

+0

*# *語法是這樣描述的:「如果* level *由#後跟一個數字組成,那麼這個數字給出一個絕對的數字號碼。」 http://www.tcl.tk/man/tcl8.5/TclCmd/uplevel.htm – 2012-07-19 03:07:31

+0

@DonalFellows不要'調用'頂部'協程'堆棧。 – 2015-03-01 07:30:05

3
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" 

這裏最裏面方法將會在電平0級和B,C在第2級和主節目將在3級,以便在PROC A如果我改變電平的值,則我可以改變任何過程的變量x的值爲a,b,c或來自方法「a」本身的主要過程。 嘗試將等級更改爲3,2,1,0並查看魔法輸出。