2009-10-20 103 views
11

將列表傳遞給Tcl過程的規範方法是什麼?將列表傳遞給Tcl過程

我真的很喜歡它,如果我能得到它,以便一個列表自動擴展到可變數量的參數。

這樣類似:

set a {b c} 
myprocedure option1 option2 $a 

myprocedure option1 option2 b c 

是等價的。

我確信我之前看到過這個,但是我無法在網上找到它。任何幫助(和代碼),使兩個案件相當,將不勝感激。

這是否被認爲是標準的Tcl慣例。或者我甚至會吠叫錯誤的樹?

+0

在最好的問題的某個地方添加「unwrap」這個詞(最好在「unwrap arguments」中)?我很難找到它:-) – cfi 2012-03-07 22:32:27

回答

14

這取決於中Tcl的版本,您正在使用,但: 8.5:

set mylist {a b c} 
myprocedure option1 option2 {*}$mylist 

8.4及以下:

set mylist {a b c} 
eval myprocedure option1 option2 $mylist 
# or, if option1 and 2 are variables 
eval myprocedure [list $option1] [list $option2] $mylist 
# or, as Bryan prefers 
eval myprocedure \$option1 \$option2 $mylist 
+1

...雖然我個人發現\ $ option1 \ $ option2比[list $ option1] [list $ optio2]更可取。它更接近地表明意圖 - 您的意圖不是創建一個元素列表,您的意圖是防止(或防止)這些變量的額外一輪替代。 – 2009-10-20 20:27:27

+0

對於8.4和以下版本,執行此操作的規範方法是:'eval [linsert $ mylist 0 myprocedure options1 option2]' – 2009-10-21 00:29:09

+2

我不同意這是規範的(但也許我們有不同的規則?)。這可以說是最安全的,但它的可讀性比\ $ option1 \ $ option2的可讀性要差,並且有點模糊了您實際嘗試完成的內容。 – 2009-10-21 02:56:52

0

要擴大RHSeeger的答案,你會編寫我的過程與特殊args這樣的說法:

proc myprocedure {opt1 opt2 args} { 
    puts "opt1=$opt1" 
    puts "opt2=$opt2" 
    puts "args=[list $args]" ;# just use [list] for output formatting 
    puts "args has [llength $args] elements" 
} 
+0

我不同意你必須編寫myprocedure來獲取可變數目的參數(即使用「args」)。不管你是這樣做的,完全取決於你是否需要輸入可變數量的輸入,而不是取決於一個特定的調用者是如何使輸入可用的。 – RHSeeger 2009-10-21 03:08:48

0

這可能是有用的注意,通過您的命令catch也將解決這個問題:

set a {b c} 
if [catch "myprocedure option1 option2 $a"] { 
    # handle errors 
} 

這也許應該,如果你想在這一點上,以處理myprocedure錯誤在你的代碼,這樣你不僅可以使用不必擔心重新拋出任何被發現的錯誤。