Когда вы uplevel
(до уровня, отличного от вашего), код, который вы там запускаете, не может получить доступ к локальным переменным команды, которая выполняет uplevel
. Там нет uplevel -1
или upvar -1
. Это потому, что вы можете тривиально вызвать код, который выполняет другой uplevel
, и нет способа описать, какая ветвь дерева должна идти вниз:
originalCall
|______________
| | |
foo get something
Если у вас есть какой-то токен состояния (например, имя переменной, которое невозможно угадать), вам придется явно указать это сценарию, который foo
использует для запуска uplevel
. Вы можете сделать это, добавив его в качестве элемента списка (действительно полезно только для стиля сценария «командный префикс»), подставив его перед запуском или установив значение переменной вызывающего в значение. Этот третий случай является одним из основных применений для upvar
, и он очень хорошо работает в терминах API, если вызывающий абонент назначает переменную для записи:
proc foo {varName} {
upvar 1 $varName var
# You can keep your own private copy as well; that's trivial
set var <someValue>
uplevel 1 {<script>}
}
Конечно, это означает, что вызывающий должен управлять уникальностью и т. Д.… Но на практике это действительно легко.