| Module-Extract-Namespaces documentation | Contained in the Module-Extract-Namespaces distribution. |
eval)Module::Extract::Namespaces - extract the package declarations from a module
use Module::Extract::Namespaces;
# in scalar context, extract first package namespace
my $namespace = Module::Extract::Namespaces->from_module( 'Foo::Bar' );
if( Module::Extract::Namespaces->error ) { ... }
# in list context, extract all namespaces
my @namespaces = Module::Extract::Namespaces->from_file( $filename );
if( Module::Extract::Namespaces->error ) { ... }
This module extracts package declarations from Perl code without running the code.
It does not extract:
eval)****NOT YET IMPLEMENTED****
Extract the namespaces declared in MODULE. In list context, it returns all of the namespaces, including possible duplicates. In scalar context it returns the first declared namespace.
If it cannot find MODULE in @INC, it returns undef in scalar context and the empty list in list context.
On failure it returns nothing, but you have to check with error to
see if that is really an error or a file with no namespaces in it.
Extract the namespaces declared in FILENAME. In list context, it returns all of the namespaces, including possible duplicates. In scalar context it returns the first declared namespace.
If FILENAME does not exist, it returns undef in scalar context and the empty list in list context.
On failure it returns nothing, but you have to check with error to
see if that is really an error or a file with no namespaces in it.
Return the base class for the PDOM. This is PPI by default. If you want
to use something else, you'll have to change all the other PDOM methods
to adapt to the different interface.
This is the class name to use with require to load the module that
while handle the parsing.
Return the class name to use to create the PDOM object. This is
PPI::Document.
Creates the PDOM from FILENAME. This depends on calls to pdom_base_class
and pdom_document_class.
Override this method to play with the PDOM before extracting the package declarations.
By default, it strips Pod and comments from the PDOM.
Strips Pod documentation from the PDOM.
Strips comments from the PDOM.
Extract the namespaces from the PDOM. It returns a list of package names in the order that it finds them in the PDOM. It does not remove duplicates (do that later if you like).
Return the error from the last call to get_modules.
* Add caching based on file digest?
This code is in Github:
git://github.com/briandfoy/module-extract-namespaces.git
brian d foy, <bdfoy@cpan.org>
This module was partially funded by The Perl Foundation (www.perlfoundation.org) and LogicLAB (www.logiclab.dk), both of whom provided travel assistance to the 2008 Oslo QA Hackathon where I created this module.
Copyright (c) 2008, brian d foy, All Rights Reserved.
You may redistribute this under the same terms as Perl itself.
| Module-Extract-Namespaces documentation | Contained in the Module-Extract-Namespaces distribution. |
# $Id$ package Module::Extract::Namespaces; use strict; use warnings; no warnings; use subs qw(); use vars qw($VERSION); $VERSION = '0.14'; use Carp qw(croak); use PPI;
sub from_module { croak "from_module not yet implemented!";
}
sub from_file { my( $class, $file ) = @_; $class->_clear_error; unless( -e $file ) { $class->_set_error( "File [$file] does not exist!" ); return; } my $Document = $class->get_pdom( $file ); return unless $Document; my @namespaces = $class->get_namespaces_from_pdom( $Document ); if( wantarray ) { @namespaces } else { $namespaces[0] } }
sub pdom_base_class { 'PPI' }
sub pdom_document_class { 'PPI::Document' }
sub get_pdom { my( $class, $file ) = @_; my $pdom_class = $class->pdom_base_class; eval "require $pdom_class"; my $Document = eval { my $pdom_document_class = $class->pdom_document_class; my $d = $pdom_document_class->new( $file ); die $pdom_document_class->errstr unless $d; $class->pdom_preprocess( $d ); $d; }; if( $@ ) { $class->_set_error( "Could not get PDOM for $file: $@" ); return; } $Document; }
sub pdom_preprocess { my( $class, $Document ) = @_; eval { $class->pdom_strip_pod( $Document ); $class->pdom_strip_comments( $Document ); }; return 1; }
sub pdom_strip_pod { $_[1]->prune('PPI::Token::Pod') }
sub pdom_strip_comments { $_[1]->prune('PPI::Token::Comment') }
sub get_namespaces_from_pdom { my( $class, $Document ) = @_; my $package_statements = $Document->find( sub { $_[1]->isa('PPI::Statement::Package') ? $_[1]->namespace : 0 } ); my @namespaces = eval { map { /package \s+ (\w+(::\w+)*) \s* ; /x; $1 } @$package_statements }; #print STDERR "Got namespaces @namespaces\n"; @namespaces; }
BEGIN { my $Error = ''; sub _set_error { $Error = $_[1]; } sub _clear_error { $Error = '' } sub error { $Error } }
1;