projman/hlp/ru/tcl/upvar.html

101 lines
7.1 KiB
HTML
Raw Normal View History

<!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>
<p>Команда создает связи между переменными различных уровней
стека.</p>
2015-10-19 13:27:31 +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>
<h2>ОПИСАНИЕ</h2>
2015-10-19 13:27:31 +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
<p>Команда upvar позволяет упростить передачу параметра по ссылке,
а также упрощает создание новых управляющий
конструкций. Например, рассмотрим следующую процедуру:</p>
2015-10-19 13:27:31 +03:00
<pre>
proc add2 name {
upvar x
set x [expr +2]
2015-10-19 13:27:31 +03:00
}
</pre>
<p>Процедура <strong>add2</strong> вызывается с аргументом, содержащим имя
переменной и увеличивает значение этой переменной на два. Хотя
тот же результат мог быть получен с помощью команды uplevel,
команда <strong>upvar</strong> позволяет легче работать с переменными из
стека вызывающей процедуры.</p>
2015-10-19 13:27:31 +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
<p>Если переменная, созданная с помощью команды <strong>upvar</strong>,
удаляется (например, если добавить в процедуру <strong>add2</strong>
строку unset x), то реально будет удалена переменная,
связанная с x, а не сама переменная x. Нет никакого способа
удалить созданные таким образом переменные, кроме как выйти из
процедуры, в которой они были созданы. Тем не менее, возможно
связать переменную верхнего уровня с другой локальной
переменной, выполнив еще одну команду <strong>upvar</strong>.</p>
2015-10-19 13:27:31 +03:00
<h2>ОШИБКИ</h2>
2015-10-19 13:27:31 +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>