如何在tcl命名空间中定义一个proc

时间:2012-03-12 12:55:24

标签: namespaces 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;
}

在namespace :: info中定义了三个变量,但是三个过程(setcount setId setRole)没有在命名空间中声明,看起来它们是在:: info之外定义的,这是允许的吗?这是怎么回事?

2 个答案:

答案 0 :(得分:5)

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

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

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

但我知道其他人不同意我的观点。写下您喜欢的内容,因为Tcl可以适用于任何一种方案。

答案 1 :(得分:3)

namespace eval命令

  1. 如果名称空间不存在,则创建
  2. 运行从该命名空间中提供给它的代码
  3. 从命名空间内定义的过程(这是所有过程,因为默认命名空间是::)

    • 如果以绝对命名空间开头,则将在指定的命名空间中定义该命令
    • 如果前面有相对名称空间,则将相对于当前名称空间
    • 定义该命令

    就这样

    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
    }