2011-02-15 172 views
3

在tcl中是否有等同於C++ #define的命令?我已經看到了使用proc函數重載來實現「define」的方法,只是想知道是否有人知道更多starightforward的方式tcl中#define的等價物?

+3

你究竟在做什麼?編譯時黑客行爲在動態語言中沒有多大價值。 – delnan 2011-02-15 16:27:18

+0

我有一個函數重複很多,並收到相同的參數:foo $ a $ b $ c $ d和foo $ a $ b $ c $ e 所以我想定義foo_e和foo_d而不是所有的 – 2011-02-15 16:49:14

回答

4

的Tcl有一個機制,可以讓你在解釋定義aliases to procedures

如果你有

proc foo {one two three} {do something with $one $two $three} 

,你會發現你總是傳遞$ a和$ b作爲前兩個參數,你可以寫:

interp alias {} foo_ab {} foo $a $b 

現在你可以說:

foo_ab $d ;# same as "foo $a $b $d" 
foo_ab $e ;# same as "foo $a $b $e" 

例如:

proc foo {one two three} {puts [join [list $one $two $three] :]} 
set a Hello 
set b World 
interp alias {} foo_ab {} foo $a $b 
foo_ab example ;# prints "Hello:World:example" 

interp alias命令中的空括號僅表示當前的解釋器。你可以用奴隸口譯員做很多有趣的事情。

1

如果通過「接收相同的參數」,你的意思是你反覆傳遞相同的值爲$a,$b$c,那麼您擁有的一個選項是使用全局變量而不是函數參數。在調用函數之前將值存儲在它們中,然後您的函數調用簡化爲foo $d等。

2

或者,您可以定義proc以期望d和e作爲具有默認值(例如空字符串)的輸入參數。

proc foo {a b c {d ""} {e ""} }..... 

如果你想擁有的輸入參數的數量未知,你可以用這個詞args,這將在args例如創建一個包含每個值列表

proc foo {a b c args } { 
    foreach bar $args { 
     #do whatever... 
    } 
    } 

歡呼 布賴恩

+0

目前,默認參數只能在參數列表的末尾(除了尾部的`args`)。 – 2011-02-16 08:43:39

4

採用interp alias允許您使用的ab內容的別名創建時間:

interp alias {} foo_ab {} foo $a $b 

如果你需要在它被調用的時候使用的值,你需要一個輔助程序代替:

proc foo_ab args { 
    global a b 
    uplevel 1 [list foo $a $b {*}$args] 
    # Or this in older Tcl: uplevel 1 [list foo $a $b] $args 
} 

在8.5,這也可以用別名和apply書面

在8.6,您還可以通過使用tailcall優化:

interp alias {} foo_ab {} apply {args { 
    global a b 
    tailcall foo $a $b {*}$args 
}} 

你也可以使用一些其他的,骯髒的伎倆像這樣:

interp alias {} foo_ab {} namespace inscope :: {foo $a $b} 

這並不是特別快,雖然,但它確實在所有Tcl 8. *版本中工作。