2012-04-27 32 views
2

這是Tcl 8.4。如何使用參數列表中的參數調用過程

我正在試圖做一個程序,可以做任何其他程序通過用戶指定的共同點。

例如:

proc process_menu_item {command args {count 1}} { 
    set inf  [expr {$count == -1 ? 1 : 0}] 
    set end_str [expr {$count == -1 ? "inf" : $count}] 
    set loop_cnt 0 

    while {$inf || $count > 0} { 
     incr loop_cnt 
     puts [format "------- %s -------" [bold "LOOP $loop_cnt of $end_str"]] 

     $command $args 
    } 
    return 
} 

這個過程,我希望,將只執行指定$命令$ count次。 我遇到的問題是傳遞參數。

假設我想打電話給這樣一個過程:

proc example {{par_a {-1}} {par_b {-1}} {par_c 1}} { 
    puts "All params: $par_a $par_b $par_c" 
} 

如何我應該叫process_menu_item?它甚至有可能嗎?我嘗試了一個字符串,一個列表,但最終par_a得到所有參數的大列表。

謝謝。

回答

3

(首先,在args參數的程序只有當它是最後的時候纔是神奇的,把它放在它後面,它就變成了一個普通的變量,當然,這可能就是你在這裏所需要的!)

召喚出process_menu_item,你會想改變:

$command $args 

這個(TCL 8.4或更早):

eval $command $args 

好吧,如果你是偏執其實寫這:

eval [list $command] [lrange $args 0 end] 

或者你使用的Tcl 8.5(或更高版本):

$command {*}$args 

然後,你可能會建立呼叫process_menu_item這樣的:

process_menu_item frobnicate [list foo bar] 

還有一些其他的方法來做到這一點,而不是使用list(許多Tcl命令可以產生列表)或你可以使用文字:

process_menu_item frobnicate {foo bar} 

什麼不建議是把任何東西在字面上是指內部process_menu_item變量(這將在與最短的基於eval的表單一起工作)。它可以讓你做出令人敬畏的東西,但它也令人難以置信的脆弱。如果你想傳遞循環變量,這很可能,但它需要更高級的技術(你應該問另一個問題)。

2

你總是可以構建一個包裝函數:

proc wrapper {arg_list} { 
    example [lindex $arg_list 0] [lindex $arg_list 1] [lindex $arg_list 2] 
} 

TCL 8.5具有專爲這樣的事情的{*} operator

% proc test {a b c} { 
    puts a 
    puts b 
    puts c 
} 
% 
% set inp [list "A" "B" "C"] 
A B C 
% test $inp 
wrong # args: should be "test a b c" 
% test {*}$inp 
a 
b 
c 
+0

因此,必須爲每個可以調用的過程編寫包裝器? – ilya1725 2012-04-28 00:21:37

0

我現在無法給出更全面的答案,但interp alias可能會讓你想要去的地方。有一個例子at rosettacode.org。如果不適合,也許探索command traces - 那些爲每個命令啓動的,你可以根據命令名進行選擇。

相關問題