Why call walkoptree() yourself (see B.pm) when you have the power of XPath (at least as much as Class::XPath supports?
#!perl use strict; use warnings; use B::XPath; use vars qw( $foo $bar ); sub some_sub { my $x = shift; $foo = $x; print "\$x is $x\n\$foo is $foo\n"; } my $node = B::XPath->fetch_root( \&some_sub ); for my $bar ($node->match( '//gvsv[@NAME="foo"]' )) { printf( "Found global '%s' at %s:%d\n (defined at %s:%d)\n", map { $bar->$_ } qw( NAME find_file find_line FILE LINE ) ); }
I'm sure you're on the edge of your seat for the output:
$ perl find_global_name.pl Found global 'foo' at find_global_name.pl:13 (defined at /usr/lib/perl5/5.8.6/vars.pm:35) Found global 'foo' at find_global_name.pl:14 (defined at /usr/lib/perl5/5.8.6/vars.pm:35
There are two drawbacks (besides the fact that it's a proof of concept and not releasable yet): Class::XPath has little axis support and you have to know an awful lot about the structure of the optree for which you want to search. I think the latter is solvable, but it will require more thought.
If you want more axis, indeed complete XPath support, at the cost of more pre-requisites and having to write a more complete customization, you could use XML::XPath as your base instead of Class::XPath.
You can have a look at XML::DOM::XPath, Tree::DAG_Node::XPath and at eXtending XML::XPath for more info.