I was debugging someone else's code and was trying to track down where in a maze of namespaces a particular piece of data was stored. This prompted me to create this little proc which lets you search all known variables for a given string.
It's very simplistic, but solved my problem du jour.
Bryan Oakley 18-Oct-2001
# finds variables whose value matches the given pattern. All variables # in the given namespace and all children of the namespace are considered. # # pattern must be of the form expected by [string match]. Note that the # pattern is fed directly to [string match]. So to find a string that # contains the fragment foo you must specify a pattern of *foo*. Otherwise # you'll only find variables that contain precisely "foo". # # This program returns a list. Each element is a string of the form # "variablename: value". proc vargrep {pattern {ns ::}} { set result {} # loop over all variables in the given namespace foreach var [info vars ${ns}::*] { if {[array exists $var]} { # this is an array; search through all elements foreach element [array names $var] { if {[string match $pattern [set ${var}($element)]]} { lappend result "${var}($element): [set ${var}($element)]" } } } else { # this is a scalar... search just the variable if {[string match $pattern [set $var]]} { lappend result "$var: [set $var]" } } } # now do the same for all children of this namespace foreach child [namespace children $ns] { set tmp [vargrep $pattern $child] set result [concat $result $tmp] } return $result }
JMN 2004-05-19 Note the above code breaks for variable declarations where no value has yet been assigned. e.g
namespace eval test { variable blah }
%vargrep something can't read "::test::blah": no such variable %array exists ::blah::hmm 0 %info exists ::blah::hmm 0
I'd suggest wrapping the scalar if {[string match ... section in a simple catch. (rather than an info exists, as presumably such cases are the exception)