了解 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 是一个过程。对上述代码的一点解释也可能使事情变得清晰。

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

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

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

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

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

你有很多句法问题,会给你带来很多悲伤。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因为它已经知道您正在使用哪个命名空间并且您在其他地方使用非限定名称)。

最新更新