关于Tcl中命名空间的问题

时间:2011-06-29 07:22:44

标签: namespaces export tcl

我在Tcl中有两个关于命名空间的问题。

namespace eval ::dai {
         set a 5
         set b 10
         namespace export *
}

我的问题是:

  1. export * - 导出会使此命名空间中的某些变量可以在其他命名空间中使用,但这个export *是什么意思?

  2. 设置5,我们不应该使用variable a 5吗?他们是一样的吗?一些教程说在命名空间内,我们应该使用variable,命名空间中variableset之间有什么区别?

2 个答案:

答案 0 :(得分:7)

1)对于Unix用户来说(原本应该是)合乎逻辑的,“*”表示“目前可用的一切”。就像在shell中执行rm -f *一样,shell会扩展“*”并将其替换为当前目录中存在的所有文件的列表。实际上,作为namespace manual states,您可以指定比简单的“*”更精细的图案。要了解那里提到的“全球式”事物的含义,请阅读string match

2)“我们不应该使用......”的问题是不正确的,因为这取决于你想做什么。如果要声明位于命名空间中的变量,请使用variable。如果要设置变量,请使用set,但是如果命名空间中不存在该变量x,则Tcl将尝试使用此名称查找全局变量,请参阅:

% set x 5
5
% namespace eval foo {
    set x 10
  }
10
% set x
10
# ^^ observe that the global variable has been assigned
% namespace eval foo {
    variable x
    set x 20
  }
20
% set x
10
# ^^ observe that now `set x 20` found the variable `x` in the namespace and assigned to it

"NAME RESOLUTION" section of the namespace man page中解释了这一点。

请注意,此行为可能看似不合逻辑,但它实际上与过程范围的行为相匹配:如果您在过程体中执行set foo bar,则表示设置 local 变量,除非您声明否则使用globalvariable或使用完全限定名称(例如::ns::foo)。

答案 1 :(得分:2)

namespace export仅适用于命名空间中的命令(即proc s):它将它们注册为有资格导入另一个命名空间。例如:

% package require textutil
0.7.1
% textutil::splitx abcdefghij {[aeiou]}
{} bcd fgh j
% splitx abcdefghij {[aeiou]}
invalid command name "splitx"
while evaluating {splitx abcdefghij {[aeiou]}}
% namespace import textutil::*
% splitx abcdefghij {[aeiou]}
{} bcd fgh j