понедельник, 21 января 2019 г.

Пространство имен (namespace) в языке Tcl

Что такое Пространство имен?

Пространство имен (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

Еще несколько слов об уточненных именах. Все пространства имен должны иметь не пустое имя кроме глобального пространства имен. Символ :: не допускается ни в команде, ни в переменных, ни в пространстве имен, за исключением использования символа как разделитель имен пространств имен. Лишние двоеточия в любом месте разделителя части имени пространства имен игнорируются; т. е. Два или более двоеточия рассматриваются как разделитель. Символ :: в конце уточненного имени переменной или команды ссылается к переменной или команде с именем {}. Кроме того, символы :: в конце уточненного имени пространства имен игнорируется.

X-Plane 11, 12 - любитель, Фото любитель со стажем

Постоянные читатели

Архив блога