2018-02-05 17:22:04 +03:00
|
|
|
|
<!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN>
|
2015-10-19 13:27:31 +03:00
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
|
<title>upvar</title>
|
|
|
|
|
</head>
|
|
|
|
|
|
|
|
|
|
<body>
|
|
|
|
|
<h1>upvar</h1>
|
|
|
|
|
|
2018-02-05 17:22:04 +03:00
|
|
|
|
<p>Команда создает связи между переменными различных уровней
|
|
|
|
|
стека.</p>
|
2015-10-19 13:27:31 +03:00
|
|
|
|
|
2018-02-05 17:22:04 +03:00
|
|
|
|
<h2>СИНТАКСИС</h2>
|
2015-10-19 13:27:31 +03:00
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
<strong>upvar</strong> ?<em>level</em>? <em>otherVar</em> <em>myVar</em> ?<em>otherVar</em> <em>myVar</em>...?
|
|
|
|
|
</pre>
|
|
|
|
|
|
2018-02-05 17:22:04 +03:00
|
|
|
|
<h2>ОПИСАНИЕ</h2>
|
2015-10-19 13:27:31 +03:00
|
|
|
|
|
2018-02-05 17:22:04 +03:00
|
|
|
|
<p>Команда позволяет одной или больше локальным переменным текущей
|
|
|
|
|
процедуры ссылаться на переменные процедуры, стоящей выше в
|
|
|
|
|
стеке, или на глобальные переменные. Аргумент <em>level</em> может
|
|
|
|
|
иметь те же формы, что и в команде <a
|
|
|
|
|
href=uplevel.html><strong>uplevel</strong></a>, или быть опущен, если
|
|
|
|
|
первый символ в первой из <em>otherVar</em> отличен от цифры и от
|
|
|
|
|
# (значение по умолчанию 1). Для каждой пары аргументов
|
|
|
|
|
<em>otherVar</em> <em>myVar</em> команда позволяет сделать
|
|
|
|
|
переменную с именем <em>otherVar</em> из указанного уровня стека
|
|
|
|
|
(локальную переменную одной из вызывающих процедур или
|
|
|
|
|
глобальную переменную, если <em>level</em> равно #0) видимой в
|
|
|
|
|
исполняемой процедуре под именем <em>myVar</em>. Переменная с
|
|
|
|
|
именем <em>otherVar</em> не обязана существовать в момент
|
|
|
|
|
исполнения команды. При необходимости она будет создана при
|
|
|
|
|
первом использовании переменной <em>myVar</em>. В момент
|
|
|
|
|
исполнения команды не должно быть доступной переменной myVar.
|
|
|
|
|
Переменная <em>myVar</em> всегда считается простой переменной (не
|
|
|
|
|
массивом и не переменной массива). Даже если значение
|
|
|
|
|
<em>myVar</em> выглядит как имя элемента массива, например, a(b),
|
|
|
|
|
создается простая переменная. Значение <em>otherVar</em> может
|
|
|
|
|
быть именем простой переменной, массива или элемента массива.
|
|
|
|
|
Команда <strong>upvar</strong> всегда возвращает пустую строку.</p>
|
2015-10-19 13:27:31 +03:00
|
|
|
|
|
2018-02-05 17:22:04 +03:00
|
|
|
|
<p>Команда upvar позволяет упростить передачу параметра по ссылке,
|
|
|
|
|
а также упрощает создание новых управляющий
|
|
|
|
|
конструкций. Например, рассмотрим следующую процедуру:</p>
|
2015-10-19 13:27:31 +03:00
|
|
|
|
<pre>
|
|
|
|
|
proc add2 name {
|
2018-02-05 17:22:04 +03:00
|
|
|
|
upvar x
|
|
|
|
|
set x [expr +2]
|
2015-10-19 13:27:31 +03:00
|
|
|
|
}
|
|
|
|
|
</pre>
|
2018-02-05 17:22:04 +03:00
|
|
|
|
<p>Процедура <strong>add2</strong> вызывается с аргументом, содержащим имя
|
|
|
|
|
переменной и увеличивает значение этой переменной на два. Хотя
|
|
|
|
|
тот же результат мог быть получен с помощью команды uplevel,
|
|
|
|
|
команда <strong>upvar</strong> позволяет легче работать с переменными из
|
|
|
|
|
стека вызывающей процедуры.</p>
|
2015-10-19 13:27:31 +03:00
|
|
|
|
|
2018-02-05 17:22:04 +03:00
|
|
|
|
<p>Команда <a href=namespace.html#eval><strong>namespace eval</strong></a>
|
|
|
|
|
так же, как и вызовы процедур, изменяет контекст, в котором
|
|
|
|
|
выполняются команды. Для каждой команды <a
|
|
|
|
|
href=namespace.html#eval><strong>namespace eval</strong></a> создается
|
|
|
|
|
дополнительный уровень в стеке. Соответственно, при указании
|
|
|
|
|
уровня контекста в стеке каждую вложенную команду <a
|
|
|
|
|
href=namespace.html#eval><strong>namespace eval</strong></a> надо
|
|
|
|
|
считать наравне с вызовом процедуры. Это относится также к
|
|
|
|
|
командам <a href=uplevel.html><strong>uplevel</strong></a> и <a
|
|
|
|
|
href=info.html#level><strong>info level</strong></a>. Например,
|
|
|
|
|
команда <strong><a href=info.html#level>info level</a> 1</strong>
|
|
|
|
|
вернет список, описывающий самую верхнюю выполняемую команду,
|
|
|
|
|
которая является либо вызовом процедуры, либо командой <a
|
|
|
|
|
href=namespace.html#eval><strong>namespace eval</strong></a>.
|
|
|
|
|
Независимо от использования команда <a href=
|
|
|
|
|
namespace.html#eval><strong>namespace eval</strong></a> команда
|
|
|
|
|
<strong>uplevel #0</strong> выполнит соответствующий скрипт на уровне
|
|
|
|
|
глобальных переменных (в глобальном пространстве имен).</p>
|
2015-10-19 13:27:31 +03:00
|
|
|
|
|
2018-02-05 17:22:04 +03:00
|
|
|
|
<p>Если переменная, созданная с помощью команды <strong>upvar</strong>,
|
|
|
|
|
удаляется (например, если добавить в процедуру <strong>add2</strong>
|
|
|
|
|
строку unset x), то реально будет удалена переменная,
|
|
|
|
|
связанная с x, а не сама переменная x. Нет никакого способа
|
|
|
|
|
удалить созданные таким образом переменные, кроме как выйти из
|
|
|
|
|
процедуры, в которой они были созданы. Тем не менее, возможно
|
|
|
|
|
связать переменную верхнего уровня с другой локальной
|
|
|
|
|
переменной, выполнив еще одну команду <strong>upvar</strong>.</p>
|
2015-10-19 13:27:31 +03:00
|
|
|
|
|
2018-02-05 17:22:04 +03:00
|
|
|
|
<h2>ОШИБКИ</h2>
|
2015-10-19 13:27:31 +03:00
|
|
|
|
|
2018-02-05 17:22:04 +03:00
|
|
|
|
<p>Если <em>otherVar</em> есть элемент массива, то отслеживание
|
|
|
|
|
массива в целом, заданной командой <a href=
|
|
|
|
|
trace.html><strong>trace</strong></a>, не сработает при действиях с
|
|
|
|
|
<em>myVar</em> (однако, если отслеживание было задано на
|
|
|
|
|
отдельный элемент массива, оно сработает). В частности,
|
|
|
|
|
изменения, сделанные с помощью <em>myVar</em> в массиве <a
|
|
|
|
|
href=tclvars.html#env><strong>env</strong></a>, не будут корректно
|
|
|
|
|
переданы подпроцессу.
|
2015-10-19 13:27:31 +03:00
|
|
|
|
</p>
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|
2018-02-05 17:22:04 +03:00
|
|
|
|
|