了解使用Tcl命名空间变量

时间:2016-03-07 06:01:19

标签: tcl

我有一个命名空间变量,定义如下:

   namespace eval ::SMB::{
      variable SmbInfo
      ------
      ------

    proc ::SMB::SmbCreate {name dutport} {
        variable SmbInfo
        global DutPorts DutPort_2 DutPorts_3 smb

        ------
        ------
        if{"" != [info command SMB::$name]} {
           return -code error "command name \"$name\" already exists"
        }
        set SmbInfo($name -DutPort) $dutport

我是Tcl的新手并试图理解上面的代码。几个问题,如果我在任何时候错了,请纠正我:

  1. 在命名空间顶部定义的变量SmbInfo将被过程SmbCreate中声明的变量覆盖。我无法弄清楚这条线的目标是什么:

         set SmbInfo($name -DutPort) $dutport
    

    我可以看到'DutPorts'被定义为全局但我找不到'DutPort'。我还没有执行代码。这可能是一个错误吗?

  2. 是($ name - DutPort)为变量SmbInfo创建数组索引,$ dutport的值是否设置为该特定数组变量?

  3. 我在文件中有类似的代码结构,如下所示

    set SmbInfo($name - SmbSetDmac) [BuildMac1 $SmbInfo($from_name-DutPort)]
    

    BuildMac1是一个程序。对上述代码的一些解释也可能使事情变得清晰。

  4. 如果我错过了在问题中发帖的任何内容,请指点我,我会编辑我的问题。 提前谢谢。

2 个答案:

答案 0 :(得分:1)

  1. 第二个声明不会覆盖,在两种情况下它都是相同的变量。
  2. 由于$ name之后的空格,该命令是语法错误。目的似乎是将$ dutport的值赋给SmbInfo的成员,该成员的名称为" $ name -DutPort" (其中$ name由变量值替换)。
  3. 类似的赋值,但这里的值来自命令的结果。
  4. 代码中存在一些语法错误,这里和那里的空格太多或太少。这个代码似乎不太可能被执行过。

    smb :: SmbCreate命令的目的似乎是1)在由第一个参数命名的SMB命名空间中创建一个新命令(除非这样的命令已经存在)和2)在SmbInfo命名空间变量中存储元数据,索引a)name参数和b)关键字,如-DutPort或-SmbSetDmac。

    像这样的代码本质上实现了一个特殊的面向对象的接口。如果空白问题得到解决,它应该可以正常工作。

答案 1 :(得分:1)

你有很多语法问题会让你感到悲伤。 Tcl非常关注它的语法级别,其中包括空格和换行符的确切位置,以及是否有{括号}[括号]。你必须让这些事情正确。

查看您遇到问题的具体代码,这一行:

    set SmbInfo($name -DutPort) $dutport

似乎极不可能,因为当只需要一个或两个时,它会向set命令传递三个参数。我猜你有一个命令,你正在调用获取一个数组的键,因此代码应该是这样的:

    set SmbInfo([$name -DutPort]) $dutport

查看[方括号]?他们在这里很重要,因为他们说“将我的内容作为一个小的下标运行并使用结​​果”。有了这个问题,还有$name -DutPort是否有效的问题,但你必须在那里得到错误信息的指导。 Tcl通常会提供非常好的错误消息,但有时您必须考虑为什么代码处于给出该消息的状态以便弄清楚实际问题是什么。你知道,通常调试......

我希望会遇到类似的问题:

set SmbInfo($name - SmbSetDmac) [BuildMac1 $SmbInfo($from_name-DutPort)]

并猜测它实际上应该是:

set SmbInfo([$name -SmbSetDmac]) [BuildMac1 $SmbInfo([$from_name -DutPort])]

再次注意我已修改空格以遵循现有模式(我猜测它是属性访问;它看起来像是OTcl或XOTcl)并添加了括号。

最后,这一行:

    if{"" != [info command SMB::$name]} {

在语法上也是错误的,应该是:

    if {"" != [info command SMB::$name]} {

这个额外的空间很重要,因为它将作为命令名称(if)的单词与作为条件表达式的单词分开。该行的其余部分可能是正确的(SMB::$name可能是可疑的,除非您在info command中使用它,但之后您可能只需要info command $name因为它已经知道什么是命名空间你在工作,你在其他地方使用不合格的名字。)