Пространства имен

Материал из Egghelp.ru - TCL/TK Eggdrop Wiki
(перенаправлено с «Namespaces»)
Перейти к: навигация, поиск

Зачем нужны пространства имен - namespace? Если Вы когда-нибудь писали свои скрипты - Вы знаете о возможных конфликтах имен переменных, созданных в глобальном пространстве имен. Пространства имен позволяют скриптеру помещать переменные и процедуры в единый именованный "блок" Tcl, так, чтобы они не конфликтовали с глобальным пространством имен. Рассмотрим простейшие пример пользовательского пространства имен

 namespace eval MyScript {
   set response "Hello World!"
   bind pub - "hi" MyScript::respond
   proc respond {nick uhost hand chan text} {
     variable response
     puthelp "PRIVMSG $nick :$response"
     return 1
   }
 }

MyScript - это имя созданного пространства имен. Оно будет использоваться в качестве префиксов в именах переменных и процедур, если они будут использоваться вне этого пространства (например, из глобального пространства имен или из других скриптов с собственными пространствами имен). Обратите внимание, что команда bind требует указания полного имени процедуры, в том числе и префикса, даже если она используется внутри этого пространства. Переменная response находится внутри пользовательского пространства, не пересекаясь с глобальным. Команда variable позволяет использовать переменные, заданные в текущем пространстве имен. В отличии от глобальных переменных, команда variable может использовать только одну переменную в качестве параметра. Если Вам нужно вызвать несколько переменных из пользовательского пространства - разместите конструкции variable <varName> на отдельных строках (или разделите точкой с запятой ";").

 catch MyScript::uninstall
 namespace eval MyScript {
   set response "Hello World!"
   bind pub - "hi" MyScript::respond
   proc respond {nick uhost hand chan text} {
     variable response
     puthelp "PRIVMSG $nick :$response"
     return 1
   }
   bind evnt - prerehash MyScript::uninstall
   proc uninstall {args} {
     unbind pub - "hi" MyScript::respond
     unbind evnt - prerehash MyScript::uninstall
     namespace delete MyScript
   }
 }

Чтобы пользователям не приходилось использовать команду .restart для удаления скрипта, хорошим тоном будет создать процедуру удаления по команде rehash. Если пользователь не удалит загрузку скрипта из конфигурационного файла Eggdrop - он будет спокойно загружен после rehash. Во-первых, триггеры не являются частью пространства имен, поэтому их нужно удалять отдельно. Во-вторых, есть возможность полностью удалить пространство имен со всеми объявленными переменными и процедурами. Не забудьте так же удалить все активные таймеры, присутствующие в скрипте! Чтобы позволить пользователям удалять/устанавливать скрипт через DCC команду .tcl source scripts/myscript.tcl необходимо добавить вызов процедуры деинсталляции в начало скрипта. Ключевое слово catch используется, чтобы бот не отключился если процедуры деинсталляции еще не объявлено (при первом запуске).

 set ns "MyScript"
 catch ${ns}::uninstall
 namespace eval $ns {
   unset ::ns
   set response "Hello World!"
   bind pub - "hi" [namespace current]::respond
   proc respond {nick uhost hand chan text} {
     variable response
     puthelp "PRIVMSG $nick :$response"
     return 1
   }
   bind evnt - prerehash [namespace current]::uninstall
   proc uninstall {args} {
     unbind pub - "hi" [namespace current]::respond
     unbind evnt - prerehash [namespace current]::uninstall
     namespace delete [namespace current]
   }
 }

Если Вы хотите избежать потенциального конфликта имен с другими пользовательскими пространствами имен - попробуйте воспользоваться этим способом. Во-первых, объявите имя переменной в глобальном пространстве имен. Оно необходимо только для первых двух строчек скрипта, так что мы удаляем его позже, чтобы не засорять глобальное пространство имен. После этого мы можем использовать команду [[[namespace]] current] внутри пространства имен MyScript. Использование такого подхода позволяет избежать многих проблем, связанных с именованием пользовательских пространств имен.