Лучшее решение: замена расширения
Правильный подход - обеспечить, чтобы внешняя процедура (в терминах стека) правильно вызывала внутреннюю процедуру; если ожидается несколько аргументов, это то, что должно быть предоставлено. С появлением Tcl 8.5 это легко сделать с помощью небольшого языкового синтаксиса, который называется подстановка расширения :
proc abc1 {args} {
puts "$args"
array set arg $args
set l2 [array get arg]
abc {*}$l2
# Or combine the two lines above into: abc {*}[array get arg]
}
Все, что делает {*}
, это говорит о том, что остальная часть слова должна быть разбита (с использованием правил синтаксиса списка) и использоваться в качестве нескольких аргументов вместо значения по умолчанию в Tcl «одно визуальное слово образует одно слово Правила. идеально подходит для этого.
Старое решение: Eval Command
Если по какой-то причине вы все еще используете старые версии Tcl (т. Е. Tcl 8.4 или более ранние), то вместо синтаксиса выше вы используете команду eval
:
eval abc $l2
Есть несколько несколько более эффективных подходов к вышеприведенному eval
, которые вы могли бы увидеть в более старом коде; например:
eval [linsert $l2 0 abc]
eval [list abc] [lrange $l2 0 end]
# ... etc ...
Но на самом деле все они устарели на abc {*}$l2
, который короче, проще для написания и быстрее. (Он просто недоступен в версии 8.4 или более ранней, и слишком много развертываний еще предстоит обновить.) Используйте синтаксис расширения, если можете. Действительно, идиоматический код Tcl для 8.5 и более поздних версий вряд ли когда-либо будет нуждаться в eval
; степень, в которой это оказалось правдой, даже удивляла тех, кто поддерживал язык.