как определить процедуру в пространстве имен Tcl - PullRequest
2 голосов
/ 12 марта 2012

Я видел некоторый код в 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;
}

В namespace :: info определены три переменные, но три procs (setcount setId setRole) не объявлены в пространстве имен, похожеони определены вне :: info, это разрешено?как это работает?

Ответы [ 2 ]

5 голосов
/ 12 марта 2012

Процедуры определены в пространстве имен ::info. Они просто не входят в область действия namespace eval, команды, которая просто создает пространство имен, если необходимо, а затем выполняет данный сценарий в этом контексте. Выполнение в контексте пространства имен меняет способ, которым proc размещает команды, которые он создает, когда имена этих команд не полностью определены. Пространство имен существует независимо от вызова namespace eval. Переменные должны быть объявлены в пространстве имен; это позволяет избежать некоторых неприятных проблем с разрешением переменных, которые могут поймать людей.

Лично я предпочитаю писать такой код:

namespace eval ::foo {
    proc bar ... {
        ...
    }
}

Но я знаю, что другие люди не согласны со мной. Напишите, что вы предпочитаете, так как Tcl отлично работает с любой схемой.

3 голосов
/ 13 марта 2012

Команда namespace eval

  1. Создает пространство имен, если оно не существует
  2. Запускает код, предоставленный ему, из этого пространства имен

Procs, определенные из пространства имен (которое является всеми процессами, поскольку пространство имен по умолчанию: ::)

  • Если ему предшествует абсолютное пространство имен, эта команда будет определяться в указанном пространстве имен
  • Если ему предшествует относительное пространство имен, эта команда будет определяться относительно текущего пространства имен

Как таковой

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
}
...