user3565150
user3565150

Reputation: 914

Understanding the use of Tcl namespace variable

I have a namespace variable which is defined as below:

   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

I am new to Tcl and trying to understand the above piece of code. Few questions, please correct me if I am wrong at any point:

  1. The variable SmbInfo defined on top in namespace is getting overridden by the one declared in the procedure SmbCreate. I am unable to figure out what is the objective of the line:

         set SmbInfo($name -DutPort) $dutport
    

    I can see that 'DutPorts' is defined as global but I could not find 'DutPort'. I have not executed the code yet. Could it be an error?

  2. Is ($name - DutPort) creating an array index for the variable SmbInfo and the value of $dutport is being set to that particular array variable?

  3. I have similar code structures in the file like below

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

    Where BuildMac1 is a procedure. A bit explanation of the above code might also make the thing clear.

If anything I missed to post in the question, kindly point me, I will edit my question. Thanks in advance.

Upvotes: 0

Views: 339

Answers (2)

Donal Fellows
Donal Fellows

Reputation: 137767

You have many syntactic problems that are going to cause you much grief. Tcl cares very much about its syntax level, which includes exactly where the spaces and newlines are, and whether there are {braces} and [brackets] as expected. You must get these things right.

Looking at the specific code you're having problems with, this line:

    set SmbInfo($name -DutPort) $dutport

would appear to be highly unlikely, as it is passing three arguments to the set command when that only takes one or two. I'd guess that you've got a command that you're calling to obtain a key for an array, and that the code therefore ought to be this:

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

See those [brackets]? They matter here, as they say “run my contents as a little subscript and use the result”. With that sorted out, there's also the question of whether $name -DutPort works at all, but you'll just have to be guided by the error messages there. Tcl usually gives very good error messages, though sometimes you have to think about why the code got in the state where it is giving that message in order to figure out what the actual problem is. You know, usual debugging…

I would expect similar problems with:

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

and would guess that it is actually supposed to be:

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

Note again that I have modified the spaces to follow the existing pattern (which I'm guessing is a property access; it looks like it's OTcl or XOTcl) and added brackets.

Finally, this line:

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

is also syntactically wrong, and should instead be:

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

That extra space matters, because it separates the word that is the command name (if) from the word that is the condition expression. The remainder of the line is probably correct (the SMB::$name might be suspicious, except you're using it in info command, but then you probably only need info command $name as it already knows about what namespace you're working in and you're using the unqualified name elsewhere).

Upvotes: 1

Peter Lewerin
Peter Lewerin

Reputation: 13282

  1. The second declaration doesn't override, it's the same variable in both cases.
  2. The command is a syntax error because of the space after $name. The intent seems to be to assign the value of $dutport to the member of SmbInfo that has the name "$name -DutPort" (where $name is replaced by the variable value).
  3. A similar assignment, but here the value comes from the result of the command.

There are a few syntax errors in the code, too many or too few spaces here and there. It seems unlikely this code has ever been executed.

The purpose of the smb::SmbCreate command would seem to be to 1) create a new command in the SMB namespace named by the first parameter (unless such a command already exists) and 2) store metadata in the SmbInfo namespace variable, indexed by a) the name parameter and b) a keyword such as -DutPort or -SmbSetDmac.

Code like this essentially implements an ad-hoc object-oriented interface. If the whitespace issues are resolved, it should work fine.

Upvotes: 1

Related Questions