2011-02-15 120 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. *版本中工作。