Получение неоцененных аргументов tcl

Что я хочу сделать, так это проанализировать аргумент tcl proc как строку без какой-либо оценки. Например, если бы у меня был тривиальный процесс, который просто выводит свои аргументы:

proc test { args } {
    puts "the args are $args"
}

То, что я хотел бы сделать, это вызвать его с помощью:

test [list [expr 1+1] [expr 2+2]]

И НЕ заставляйте tcl оценивать [list [expr 1+1] [expr 2+2]]. Или даже если бы он оценил это, я бы все равно хотел иметь исходную командную строку. Таким образом, с помощью тривиального «тестового» процесса выше я хотел бы иметь возможность вернуться:

the args are [list [expr 1+1] [expr 2+2]]

Возможно ли это в tcl 8.4?


person MVP    schedule 11.04.2012    source источник


Ответы (2)


Вы не можете сделать это с Tcl 8.4 (и ранее); дизайн языка делает это невозможным. Исправление заключается в передаче аргументов без оценки (и заключенных в фигурные скобки). Затем вы можете распечатать их, как вам нравится. Чтобы получить их оценочную форму, вам нужно сделать это внутри вашей процедуры:

set evaluated_x [uplevel 1 [list subst $unevaluated_x]]

Это более чем беспорядочно!


Если бы вы использовали Tcl 8.5, у вас была бы другая альтернатива:

set calling_code [dict get [info frame -1] cmd]

info frame -1 получает словарь, содержащий описание текущей команды в контексте, вызвавшем текущую процедуру, а его ключ cmd представляет собой фактическую командную строку до применения правил подстановки. Это должно быть то, что вы хотите (хотя имейте в виду, что оно включает само имя команды).

Это недоступно для версии 8.4 и никогда не будет перенесено обратно. Возможно, вы захотите обновиться!

person Donal Fellows    schedule 11.04.2012
comment
Спасибо. Это то, чего я боялся. - person MVP; 12.04.2012
comment
Причина, по которой я почти уверен, что info frame никогда не будет перенесено обратно в 8.4, заключается в том, что для реализации потребовалось довольно много навязчивых механизмов; это значительно усложнило реализацию Tcl в областях, которые и без того были очень сложными. Бэкпорт был бы чрезвычайно разрушительным. - person Donal Fellows; 12.04.2012

При передаче аргументов в тест заключите их в фигурные скобки , например: тест {[список [выражение 1+1] [выражение 2+2]]}

person thelazydeveloper    schedule 11.04.2012
comment
Спасибо. Но я забыл упомянуть, что список аргументов передается мне, и я не могу отредактировать аргумент, чтобы добавить фигурные скобки. - person MVP; 12.04.2012