3

我在 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之外定义的,是否允许?这是如何运作的?

4

2 回答 2

5

这些过程在命名空间中定义的::info。它们只是不在 的范围内namespace eval,该命令仅在必要时创建命名空间,然后在该上下文中执行给定的脚本。在命名空间的上下文中执行会改变proc当这些命令的名称不完全限定时它创建的命令的放置方式。命名空间独立于namespace eval调用而存在。变量必须在命名空间中声明;这避免了一些真正令人讨厌的麻烦,解决了可以抓人的变量。

就个人而言,我更喜欢这样编写代码:

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

但我知道其他人不同意我的观点。写你喜欢的,因为 Tcl 可以在任何一种方案中正常工作。

于 2012-03-12T13:15:00.443 回答
3

namespace eval命令_

  1. 如果命名空间不存在,则创建命名空间
  2. 运行从该命名空间内提供给它的代码

从命名空间中定义的 Procs(这是所有 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
}
于 2012-03-12T21:30:03.190 回答