projman/hlp/ru/tcl/upvar.html
2018-02-05 17:23:37 +03:00

101 lines
7.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN>
<html>
<head>
<title>upvar</title>
</head>
<body>
<h1>upvar</h1>
<p>Команда создает связи между переменными различных уровней
стека.</p>
<h2>СИНТАКСИС</h2>
<pre>
<strong>upvar</strong> ?<em>level</em>? <em>otherVar</em> <em>myVar</em> ?<em>otherVar</em> <em>myVar</em>...?
</pre>
<h2>ОПИСАНИЕ</h2>
<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>
<p>Команда upvar позволяет упростить передачу параметра по ссылке,
а также упрощает создание новых управляющий
конструкций. Например, рассмотрим следующую процедуру:</p>
<pre>
proc add2 name {
upvar x
set x [expr +2]
}
</pre>
<p>Процедура <strong>add2</strong> вызывается с аргументом, содержащим имя
переменной и увеличивает значение этой переменной на два. Хотя
тот же результат мог быть получен с помощью команды uplevel,
команда <strong>upvar</strong> позволяет легче работать с переменными из
стека вызывающей процедуры.</p>
<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>
<p>Если переменная, созданная с помощью команды <strong>upvar</strong>,
удаляется (например, если добавить в процедуру <strong>add2</strong>
строку unset x), то реально будет удалена переменная,
связанная с x, а не сама переменная x. Нет никакого способа
удалить созданные таким образом переменные, кроме как выйти из
процедуры, в которой они были созданы. Тем не менее, возможно
связать переменную верхнего уровня с другой локальной
переменной, выполнив еще одну команду <strong>upvar</strong>.</p>
<h2>ОШИБКИ</h2>
<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>, не будут корректно
переданы подпроцессу.
</p>
</body>
</html>