理解 Tcl 命名空间变量的使用

Understanding the use of Tcl namespace variable

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

   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 中声明的变量覆盖。我无法弄清楚行的 objective 是什么:

         set SmbInfo($name -DutPort) $dutport
    

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

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

  3. 我在文件中有类似下面的代码结构

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

    其中 BuildMac1 是一个程序。稍微解释一下上面的代码也可能会使事情变得清楚。

如果我在问题中 post 遗漏了什么,请指出我,我会编辑我的问题。 提前致谢。

  1. 第二个声明没有覆盖,在这两种情况下它是同一个变量。
  2. 由于 $name 后的 space,该命令是一个语法错误。其意图似乎是将 $dutport 的值分配给名称为“$name -DutPort”的 SmbInfo 成员(其中 $name 被变量值替换)。
  3. 一个类似的赋值,但这里的值来自命令的结果。

代码中存在一些语法错误,space 太多或太少。这段代码似乎不太可能被执行过。

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

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

你有很多句法问题,这些问题会让你很伤心。 Tcl 非常关心它的语法级别,这包括 space 和换行符到底在哪里,以及是否有 { 大括号 }[ 括号 [=19= 】 不出所料。你必须把这些事情做好。

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

    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])]

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

最后,这一行:

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

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

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

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