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.
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
.