как определить процедуру в пространстве имен tcl
-
12-12-2019 - |
Вопрос
Я видел такой код в TCL:
namespace eval ::info {
set count 0;
set id 1;
set role admin;
namespace export *
}
proc ::info::setcount {
set ::info::count 0;
}
proc ::info::setId {
set ::info::id 1;
}
proc ::info::setRole {
set ::info::role user;
}
В пространстве имен ::info определены три переменные, но эти три процедуры (setcount setId setRole) не объявлены в пространстве имен, похоже, они определены вне ::info, это разрешено?Как это работает?
Решение
Процедуры являются определены в ::info
пространство имен.Они просто не входят в сферу действия namespace eval
, команда, которая при необходимости просто создает пространство имен, а затем выполняет данный скрипт в этом контексте.Выполнение в контексте пространства имен меняет способ proc
помещает команды, которые он создает, когда имена этих команд не являются полностью определенными.Пространство имен существует независимо от namespace eval
вызов.Однако переменные должны быть объявлены в пространстве имен;это позволяет избежать действительно неприятных проблем с разрешением переменных, которые могут застать людей врасплох.
Лично я предпочитаю писать такой код:
namespace eval ::foo {
proc bar ... {
...
}
}
Но я знаю, что другие люди со мной не согласны.Напишите то, что вы предпочитаете, поскольку Tcl прекрасно работает с любой схемой.
Другие советы
А namespace eval
команда
- Создает пространство имен, если оно не существует.
- Запускает предоставленный ему код из этого пространства имен.
Процедуры, определенные внутри пространства имен (которым являются все процедуры, поскольку пространством имен по умолчанию является ::)
- Если ей предшествует абсолютное пространство имен, определит эту команду в указанном пространстве имен.
- Если ей предшествует относительное пространство имен, эта команда будет определяться относительно текущего пространства имен.
Как таковой
namespace eval bob {
namespace eval joe {
proc proc1 {} {}
}
proc proc2 {} {}
proc ::proc3 {} {}
proc joe::proc4 {} {}
}
proc proc5 {} {}
proc bob::joe::proc6 {} {}
proc ::bob::joe::proc7 {} {}
Будут существовать следующие команды
::bob::joe::proc1
::bob::proc2
::proc3
::bob::joe::proc4
::proc5
::bob::joe::proc6
::bob::joe::proc7
Обратите внимание, что перед командами в глобальном пространстве имен, вызываемыми из глобального пространства имен, может стоять ::
или нет.То же самое относится и к командам в любом пространстве имен.
namespace eval bob {
proc2 ;# calls ::bob::proc2
::proc5 ;# calls ::proc5 (proc5 in the global namespace)
joe::proc4 ;# calls ::bob::joe::proc4
}
Стоит отметить, что необработанное имя команды (без каких-либо квалификаторов пространства имен) будет искаться в текущем пространстве имен, а затем, если оно не найдет там команду, в глобальном пространстве имен.
namespace eval bob {
proc5 ;# calls ::proc5 since there is no ::bob::proc5
}