B::XPath

chromatic on 2005-04-25T06:46:08

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.


More axis support

mir on 2005-04-25T08:20:34

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.