Эквивалент #define в tcl? - PullRequest
       4

Эквивалент #define в tcl?

3 голосов
/ 15 февраля 2011

Есть ли в tcl команда, эквивалентная C ++ #define? Я видел способы реализации «определения», используя перегрузку функции proc, просто хотел узнать, знает ли кто-нибудь более простой способ

Ответы [ 4 ]

4 голосов
/ 16 февраля 2011

Использование interp alias позволяет использовать содержимое a и b во время создания псевдонима:

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:

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

В 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}

Это не особенно быстро, но работает во всех Tcl8. * версии.

4 голосов
/ 15 февраля 2011

Tcl имеет механизм, который позволяет вам определять псевдонимы процедур в интерпретаторе.

Если у вас есть

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 просто означают текущий интерпретатор.С подчиненными переводчиками можно делать много забавных вещей.

2 голосов
/ 15 февраля 2011

В качестве альтернативы вы можете определить свой процесс, ожидая, что и d, и e как входные параметры со значением по умолчанию (например, пустая строка), например,

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

Если у вас будет неизвестное количество входных параметров, вы можете использовать слово args, которое создаст список, содержащий каждое значение в args, например.

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

веселит Brian

1 голос
/ 15 февраля 2011

Если под «получает одинаковые аргументы» вы имеете в виду, что вы неоднократно передаете одни и те же значения для $a, $b и $c, то у вас есть один вариант - использовать глобальные переменные вместо параметров функции. Сохраняйте значения в них перед вызовом вашей функции, и затем ваш вызов функции упрощается до foo $d и т. Д.

...