Использование namespace/uplevel/global в TCL

У меня есть такой скрипт:

proc subProc1 { } {
    puts $var1
}
proc subProc2 { } {
    puts $var2
}

proc mainProc { args } {
    # Define many variables
    subProc1
    subProc2
    #etc.
}

Я хотел бы, чтобы subProc1 и subProc2 имели переменные, определенные в mainProc. Я могу передать их как аргументы, но это много аргументов, я бы хотел этого избежать.

Я попытался использовать команду upvar, добавив эту строку в subProcs:

subProc1 { } {
    upvar $var1 var1 $var2 var2 ;#etc
    puts $var1
    # etc.
}

Но у меня есть сообщение об ошибке «нет такой переменной», и нехорошо иметь такую ​​​​огромную строку

Я только что прочитал о пространстве имен, но я действительно не понимаю, как его использовать (плюс я не уверен, что понимаю концепцию, так что она действительно адаптирована к моему варианту использования?)


person little-dude    schedule 30.12.2013    source источник
comment
Это прокси для какого-то реального кода, где это имеет смысл? Если вы просто читаете, вы можете передать значение (эффективно!) в качестве аргумента. Tcl передает ссылку на копирование при записи, что одновременно эффективно и легко продумывается на уровне скрипта (представьте, что он всегда копирует, но быстрее).   -  person Donal Fellows    schedule 01.01.2014


Ответы (1)


upvar — правильный инструмент для этого. Другие команды можно эмулировать с помощью upvar.

Но вы ошибаетесь, называя upvar. Вы должны использовать переменную имя, а не ее значение (что приведет к ошибке "нет такой переменной").

upvar var1 var1 var2 var2 ;#...

Я бы подумал об использовании какого-то другого способа хранения данных, может быть, словаря или массива?
Это облегчило бы передачу переменных.

person Johannes Kuhn    schedule 31.12.2013
comment
Спасибо. К этой ошибке меня привели многочисленные примеры, подобные этим proc procName { var } { upvar $var var ;#... }. Такого рода вещи интересны только в том случае, если var является массивом, верно? - person little-dude; 31.12.2013
comment
Нет, вы также можете передать имя обычной (скалярной) переменной, если вы собираетесь изменить значение этой переменной, как это делает incr или set. - person Johannes Kuhn; 31.12.2013