如何在 TCL 命名空间中定义 proc



我在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 中

定义了三个变量,但是三个 procs(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
}

最新更新