NAME

PPIx::Index - index variable, subroutine and package usage in a perl document

SYNOPSIS

use PPIx::Index;

my $fn = 'somescript.pl';
my $pa = PPIx::Index->new( script => $fn );

print "scripts depended on by '$fn':\n", join "\n", $pa->script_names;

my $subs = $pa->script($fn)->subs;
print "$_ declared at $subs->{$_}\n"
  for keys %$subs;

DESCRIPTION

Given a perl script, construct variable, subroutine and package information about the script and other scripts or modules it depends on. This information, currently, covers what and where variables, subroutines and packages are used and declared within their respective files. Due to the fact that this module performs static analysis any dynamic script/module dependencies will be missed.

Purpose

This module was created with the purpose of being able to look at large amounts of legacy code and making sense out of it quickly. So given a legacy script, find where globals are declared, what is scoped to a subroutine and so on. As it stands, this module still needs further modules to produce useful output, but that's what the helper modules are for.

Historical Note

This was originally called PPIx::Analyze, but by the time I came to releasing it I realised it was just an indexer, so switched to the present name.

METHODS

new

The constructor method takes the following named parameters list:

script/file/document

The filename of the document which is to be indexd.

name_constraint

Either a coderef or an arrayref of coderefs which will be passed the name of a an include (something used or required to be indexd i.e Foo::Bar, library.pl. If one of the coderefs returns false then the include will not be indexd.

By default any core modules (from any version of perl) are skipped and PPIx::Index is skipped. To override this behaviour see. include_core and include_index.

path_constraint

Either a coderef or an arrayref of coderefs which will be passed the path of a an include (something used or required to be indexd i.e /usr/local/perl5/Carp.pm, C:\dev\perllibs\logging.pl. If one of the coderefs returns false then the include will not be indexd.

include_core

Include core modules when indexing.

include_index

Include PPIx::Index when indexing.

PPIx::Index accessor methods

script

Return the PPIx::Index::Script object representing the filename provided.

script_names

A list of script names as depended upon the base script, sorted by the order in which they are required.

scripts

A list of script objects sorted by dependency of the base script.

PPIx::Index::Script accessor methods

Each of the following accessors returns a hash where the keys are the names approriate to the accessor and values are the line numbers on which they occur.

lex_vars

Returns a hash of the lexical varables declared outside subroutines in the script e.g

{ '%seen' => 130 }
pkg_vars

Returns a hash of package variables declared or used (i.e no strictness) e.g

{ '@ISA' => 3 }
subs

Returns a hash of subroutines declared in the script e.g

{ 'new' => 21 }
packages

Returns a hash of the packages used in the script e.g

{ 'Foo::Bar' => 1 }
lex_vars_in_subs

Returns a hash where the keys are the subroutine names and the values are hashes with the variable names as the keys and the line numbers they're declared on as values e.g

{
  get_foo => {
    '$self' => 34,
    '@rest' => 34,
  },
  parse_bar => {
    '$self'  => 56,
    '$chunk' => 60,
    '$delim' => 60,
  },
}

IMPORT

When used or import is explicitly called the following parameters may be provided:

--verbose/-v

If this option is passed in then verbose output is enabled.

--quiet/-q

If this option is passed then all output relating to the module is silenced including warnings.

CAVEATS

Development release

This is a development release to give the public a peek at what's going on, so the API isn't necessarily stable and the documentation is incomplete. It also means that it is a memory and CPU hog so shouldn't be run on anything that is important, low-end or generally not robust. Have fun!

Static analysis

The very nature of PPI is a static analysis of a perl document so dynamic code is likely to yield less informative results.

BUGS

  • Currently lexical variables in anonymous subs will also look to live inside their parent subs too.

  • When subs are referred to using the code sigil e.g \&foo they are included in the package variables.

TODO

  • Write some tests already!

  • Abstract data storage, defaulting to SQLite, and cache results so indexing only needs to be performed once.

  • Cross-referencing source-highlighting HTML output module (that was the idea originally, but abstraction is nice too).

  • Store the PPI objects instead of strings, this will probably mean storing the object along with the values pointed to by the stringified object. Maybe.

  • Document internal methods and functions and just generally document more.

AUTHOR

Dan Brook <cpan@broquaint.com>

2 POD Errors

The following errors were encountered while parsing the POD:

Around line 550:

You forgot a '=back' before '=head2'

Around line 552:

'=item' outside of any '=over'