Search code examples
namespacestcl

Tcl: Getting all variables defined under a namespace


Is there any robust mechanism for getting all variables that are declared using the "variable" keyword under a given namespace?

For example, consider the following code:

namespace eval MyNamespace {
    variable showThisVar1
    set dontShowThisVar1 1
    proc MyProc { } { 
        variable showThisVar2
        set dontShowThisVar2 1            
    }  
}

I am looking for a robust way to get showThisVar1 and showThisVar2, which have been declared as variables in the namespace MyNamespace. The result of the query should not return dontShowThisVar1 and dontShowThisVar2.


Solution

  • You can use a combination of info vars and info exists.

    After running your code, as is, you can use info vars to get all the variables in MyNamespace.

    > info vars MyNamespace::*
    
    ::MyNamespace::dontShowThisVar1 
    ::MyNamespace::showThisVar1
    

    First note that showThisVar2 is not listed. This is because MyNamespace::MyProc has not been called.

    > MyNamespace::MyProc
    > info vars MyNamespace::*
    
    ::MyNamespace::showThisVar2
    ::MyNamespace::dontShowThisVar1
    ::MyNamespace::showThisVar1
    

    After calling the proc, MyNamespace::showThisVar2 has been declared in the namespace. dontShowThisVar2 doesn't appear in the list from info vars, because it is scoped to the proc.

    To only show variables which were declared with the variable command, but not actually set to a value, you could check with info exists:

    foreach var [info vars MyNamespace::*] {
         if {![info exists $var]} {
             puts $var
         }
    }
    
    ::MyNamespace::showThisVar2
    ::MyNamespace::showThisVar1
    

    Until answering your question, I didn't realize that a variable could be returned with info vars but not return a 1 with info exists.