我在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中定义了三个变量,但是命名空间中没有声明三个proc(setcount setId setRole),看起来它们是在::info之外定义的,这是允许的吗?这是如何工作的?

有帮助吗?

解决方案

程序 定义于 ::info 命名空间。他们只是不在 namespace eval, ,一个命令,它只是在必要时创建命名空间,然后在该上下文中执行给定的脚本。在命名空间的上下文中执行会改变如何 proc 放置它在这些命令的名称不完全限定时创建的命令。命名空间独立于 namespace eval 打电话。变量必须在命名空间中声明;这避免了一些真正讨厌的麻烦,解决变量,可以抓住人们。

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

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

但我知道其他人不同意我的观点。写你喜欢的东西,因为Tcl可以很好地使用任何一种方案。

其他提示

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
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top