Search code examples
arraystclincr-tcl

TCL Error: can't set "::streamID(1,10,1)": variable isn't array


I have read the thread, Cant read variable, isnt array, and I think may be related somehow, but I can't figure out how. In the following TCL snippet, a three dimensional array ::stream is tested and a value is read. The array contains a scalar ID value. The last line in the snippet creates an error that says

can't set "::streamId(1,10,1)": variable isn't array
    while executing
"set ::streamId($chas,$card,$port) $nextId"
    (procedure "getNextStreamId" line 28)

I interpret this as meaning $nextId is something other than a scalar and it can't be put into a 3 dimensional array of scalars. Is my interpretation of the error incorrect? I was pretty confident that the array holds scalar values, so I started to think maybe there is some data safety issue here.

# get current streamId
if { [ catch {info exists $::streamId($chas,$card,$port)} ] == 0 } {
if {$::testEnv(verbose) >= $verbLevel} {
    logInfo [getProcName] "pre-existing streamId found for: \
        \n dutAndPort:  $dutAndPort \
        \n ixiaPort:    {$chas $card $port}\
        \n streamId:    $::streamId($chas,$card,$port) \
        \n incrementing to next one..."
}
set nextId [ mpexpr $::streamId($chas,$card,$port) + 1 ]
} else {
if {$::testEnv(verbose) >= 0} {
    logInfo [getProcName] "No pre-existing streamId found for: \
        \n\t dutAndPort:    $dutAndPort \
        \n\t ixiaPort:      {$chas $card $port}\
        \n\t setting to 1"
}
set nextId 1
}
set curId  [ mpexpr $nextId - 1 ]

set ::streamId($chas,$card,$port) $nextId

Solution

  • In your code, I guess you wanted to check if the array ::streamId has the index $chas,$card,$port

    info exists $::streamId($chas,$card,$port)
    

    which is incorrect. You should use

    info exists ::streamId($chas,$card,$port)
    

    i.e. without dollar sign. Then only the if loop can ensure the existence of the index $chas,$card,$port.

    Then, at last you are trying to set the value of the index $chas,$card,$port to $nextId .

    set ::streamId($chas,$card,$port) $nextId
    

    which is incoorect, because it kept outside the if loop of variable existence check of the index $chas,$card,$port.

    Then the actual error message is referring the fact that there is a scalar variable named streamId exists.

    % set ::streamId 1
    1
    % set ::streamId(1,10,1) 20
    can't set "::streamId(1,10,1)": variable isn't array
    %
    

    Ensure you don't have the same variable names.