Equivalent of #define in tcl?

穿精又带淫゛_ 提交于 2019-12-04 11:41:20

Tcl has a mechanism that lets you define aliases to procedures in an interpreter.

If you have

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

and you find you're always passing $a and $b as the first two arguments, you can write:

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

And now you can say:

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

example:

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"

The empty braces in the interp alias command merely signify the current interpreter. You can do lots of fun things with slave interpreters.

The use of interp alias allows you to use the contents of a and b at the time the alias was created:

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

If you need to use the values at the time it is called, you need a helper procedure instead:

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
}

In 8.5, this can also be written with aliases and apply:

interp alias {} foo_ab {} apply {args {
    global a b
    uplevel 1 [list foo $a $b {*}$args]
}}

In 8.6, you can optimize further by using tailcall:

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

You could also use some other, dirtier tricks like this:

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

That's not especially fast though, but it does work in all Tcl 8.* versions.

Alternatively you can define your proc to expect both d and e as input parameters with a default value (e.g. empty string) e.g.

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

If you're going to have an unkown number of input parameters you can use the word args, which will create a list containing each value in args e.g.

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

cheers Brian

If by "receives the same arguments" you mean that you are repeatedly passing the same values for $a, $b, and $c, then one option you have is to use globals instead of function parameters. Store values in them before calling your function, and then your function call simplifies down to foo $d, etc.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!