Что такое Пространство имен?
Пространство
имен (namespace) это коллекция команд и
переменных. Оно (Пространство имен)
включает в себя те команды и переменные,
о которых должна быть уверенность, что
они не пересекутся с командами и
переменными из других пространств имен.
Язык Tcl имеет всегда хотя бы одно такое
пространство имен, к которому мы ссылаться
как глобальному пространству имен
(global namespace). Глобальное пространство
имен содержит все глобальные переменные
и команды. Команда namespace eval позволяет
вам создать новое пространство имен.
Например,
namespace eval Counter {
namespace
export bump
variable
num 0
proc
bump {} {
variable num
incr num
}
}
создает новое
пространство имен, содержащее переменную
num и процедуру bump. Команды и
переменные в этом пространстве имен
отделены от других команд и переменных
в этой программе. Если существует команда
с именем bump в глобальном пространстве
имен, она отличается от команды bump
в пространстве имен Counter.
Переменные
пространства имен напоминают глобальные
переменные в Tcl. Они существуют вне
процедур в пространстве имен, а получить
доступ к ним из процедур можно через
команду variable, как показано
в предыдущем примере.
Существуют
пространства имен динамически. Вы можете
добавлять и удалять команды и переменные
в любое время, так что вы можете строить
контекст пространства имен в течение
времени существования скрипта используя
серию команд namespace eval. Например, следующая
серия команд имеет тот же эффект, что и
предыдущие команды:
namespace eval Counter {
variable
num 0
proc
bump {} {
variable num
return [incr num]
}
}
namespace eval Counter {
proc
test {args} {
return $args
}
}
namespace eval Counter {
rename
test ""
}
Обратите
внимание, что процедура test первоначально
добавлена к пространству имен Counter, а
потом удалена командой rename.
Пространства
имен могут содержать внутри себя другие
пространства имен, так что образовывают
вложенную иерархию. Вложенные пространства
имен заключены внутри родительского
пространства имен и не могут пересекаться
с другими пространствами имен.
Уточненные имена
Каждое
пространство имен имеет имя такое как
history или
::safe::interp. Так как пространства имен могут
быть вложенными друг в друга, уточненные
имена используются для ссылки к командам,
переменным и пространствам имен входящим
в данное пространство имен. Уточненные
имена похожи на иерархические цепочки
имен для указания файлов в системе Unix
или виджетов в Tk, за исключением того,
что символы :: используются как разделители
вместо / или .. Самое верхнее или глобальное
пространство имен имеет имя “” (т.е.,
пустая строка), хотя :: это синоним.
Например, имя ::safe::interp::create ссылается к
команде созданной в пространстве имен
с именем interp которое
является дочерним от пространства имен
::safe, которое в свою очередь является
дочерним от глобального пространства
имен ::.
Если вы хотите
получить доступ к командам и переменным
из другого пространства имен, вы должны
использовать уточняющий синтаксис.
Имена должны быть уточнены
(qualified) именем пространства имен,
которое содержит их. Из глобального
пространства имен мы можем получить
доступ к процедурам пространства имен
Counter следующим образом:
Counter::bump 5
Counter::Reset
Мы можем
получить доступ к текущему счету примерно
так:
puts "count = $Counter::num"
Когда
какое-нибудь пространство имен содержит
другое пространство имен, вам может
потребоваться более чем одно уточняющее
имя для доступа к его элементам. Если
вы имеете пространство имен с именем
Foo, а оно включает в себя пространство
имен Counter, вы можете вызвать процедуру
bump, находясь в глобальной пространстве
имен, следующим образом:
Foo::Counter::bump 3
Также вы
можете использовать уточненные имена
когда создаете и переименовываете
команды. Например, вы можете добавить
процедуру к пространству имен с именем
Foo следующим образом:
proc Foo::Test {args} {return $args}
А вот так вы
можете переместить эту же процедуру в
другое пространство имен:
rename Foo::Test Bar::Test
Еще несколько
слов об уточненных именах. Все пространства
имен должны иметь не пустое имя кроме
глобального пространства имен. Символ
:: не допускается ни в команде, ни в
переменных, ни в пространстве имен, за
исключением использования символа как
разделитель имен пространств имен.
Лишние двоеточия в любом месте разделителя
части имени пространства имен игнорируются;
т. е. Два или более двоеточия
рассматриваются как разделитель. Символ
:: в конце уточненного имени переменной
или команды ссылается к переменной или
команде с именем {}. Кроме того, символы
:: в конце уточненного имени пространства
имен игнорируется.