как определить процедуру в пространстве имен tcl

StackOverflow https://stackoverflow.com//questions/9667392

  •  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 команда

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

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

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

Как таковой

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
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top