【问题标题】:Understanding the use of Tcl namespace variable了解 Tcl 命名空间变量的使用
【发布时间】:2016-06-20 14:44:07
【问题描述】:

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

   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 是一个过程。对上面的代码稍加解释一下,也可能会让事情变得清晰。

如果我错过了在问题中发布的任何内容,请指出我,我将编辑我的问题。 提前致谢。

【问题讨论】:

    标签: tcl


    【解决方案1】:
    1. 第二个声明不会被覆盖,它在两种情况下都是同一个变量。
    2. 该命令是语法错误,因为 $name 后面有空格。其意图似乎是将 $dutport 的值分配给名为“$name -DutPort”的 SmbInfo 成员(其中 $name 被变量值替换)。
    3. 类似的赋值,但这里的值来自命令的结果。

    代码中有一些语法错误,这里和那里的空格太多或太少。这段代码似乎不太可能被执行过。

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

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

    【讨论】:

      【解决方案2】:

      你有很多句法问题会让你非常痛苦。 Tcl 非常关心它的语法级别,包括空格和换行符的确切位置,以及是否有预期的{braces}[brackets]。你必须把这些事情做好。

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

          set SmbInfo($name -DutPort) $dutport
      

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

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

      看到那些[brackets]了吗?它们在这里很重要,正如他们所说的“将我的内容作为一个小下标运行并使用结​​果”。解决这个问题后,还有$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,因为它已经知道您正在使用的命名空间和您在其他地方使用了不合格的名称)。

      【讨论】:

      • 先断言命令不存在,然后立即调用,是不是有点奇怪?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多