题
我在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
命令
- 如果命名空间不存在,则创建命名空间
- 在该命名空间内运行提供给它的代码
从命名空间中定义的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
}
不隶属于 StackOverflow