Страница 1 из 1

Зачем нужны пространства имен?

СообщениеДобавлено: 14 июн 2009 17:48
Deniska
Зачем нужны пространства имен - namespace? Если у Вас когда-либо возникали проблемы с глобальными переменными и процедурами в Ваших скриптах, конфликты со скриптами других авторов - пространства имен это то, что Вам нужно. Пространства имен - это основная возможность, приближающая функционал TCL к объектно-ориентированным языкам программирования. Они позволяют программисту поместить переменные и процедуры внутрь именованного контейнера, что позволяет избежать конфликтов в глобальном пространстве имен.

Приступим!
TCL: [ Скачать ] [ Скрыть ]
namespace eval MyScript {
  set response "Привет Мир!"

  bind pub - "привет" MyScript::respond
  proc respond { nick uhost hand chan text } {
    variable response
    puthelp "PRIVMSG $nick :$response"
    return 1
  }
}


MyScript это имя пространства имен. Оно так же используется как префикс в именах переменных и процедур, если они вызываются извне этого пространства (например, из глобального пространства имен). Обратите внимание, что команда bind использует полное имя процедуры в качестве параметра. Еще одна важная вещь, на которую стоит обратить внимание - переменная $response находится внутри пространства имен. Это значит, что она не является глобальной переменной. Поэтому внутри процедуры она вызывается как variable, а не global. Учтите, что переменные пространства имен должны объявляться каждая на отдельной строке, если Вам требуется больше одной переменной. Они не могут объявляться в одной строке, как это делается с global переменными.

TCL: [ Скачать ] [ Скрыть ]
catch MyScript::uninstall
namespace eval MyScript {
  set response "Привет Мир!"

  bind pub - "привет" 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 - "привет" MyScript::respond
    unbind evnt - prerehash MyScript::uninstall
    namespace delete MyScript
  }
}


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

TCL: [ Скачать ] [ Скрыть ]
set ns "MyScript"
catch ${ns}::uninstall
namespace eval $ns {
  unset ::ns

  set response "Привет Мир!"

  bind pub - "привет" [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 - "привет" [namespace current]::respond
    unbind evnt - prerehash [namespace current]::uninstall
    namespace delete [namespace current]
  }
}


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

На этом всё!

Оригинал: http://www.barkerjr.net/irc/eggdrop/Scr ... spaces.php