Search code examples
stored-procedurestclargs

How to handle unexisting variables passed to a proc


I would like to create a procedure like this simple example:

proc name {args} { 
    foreach val $args {
        puts $val
    }
}

But I would like the procedure to handle variables that don't exist, something like the code shown below:

proc name {args} { 
    foreach val $args {
        if [info exists $val] {
            puts $val
        }
    }
}

The problem is that the code is not executed because as soon as I call the procedure with an unexisting variable it immediately stalls, prior to go into the code, saying that there is a variable that doesn't exist. Is it probable because the procedure checks argument existance before entering the body?.

I can make it work by changing args by several optional variables with predefined values, but that limits the procedure and makes it look bad.

Can I make a proc able to handle unexisting variables?


Solution

  • You can't pass a variable as an argument: arguments have to be values. You can pass a variable name as an argument and use that as a reference to the variable inside the procedure. Example:

    proc name args {
        foreach varname $args {
            upvar 1 $varname var
            if {[info exists var]} {
                puts $var
            }
        }
    }
    

    (The call to upvar creates a link between the variable whose name is the value of the variable varname outside the procedure and the variable called var inside the procedure. This is one way to "pass a variable to a procedure".)

    Then you can do this:

    % set foo 1 ; set baz 3
    % name foo bar baz
    1
    3
    

    Note that if you try to invoke the procedure as

    % name $bar
    

    where bar is undefined, the interpreter tries (and fails) to evaluate it before calling the procedure. That might be what you are seeing.

    Documentation: upvar