home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / Info.pm < prev    next >
Encoding:
Perl POD Document  |  2003-05-22  |  16.4 KB  |  681 lines

  1. package Module::Info;
  2.  
  3. use strict;
  4. use Carp;
  5. use File::Spec;
  6. use Config;
  7. require 5.004;
  8.  
  9. use vars qw($VERSION);
  10. $VERSION = '0.20';
  11.  
  12.  
  13. =head1 NAME
  14.  
  15. Module::Info - Information about Perl modules
  16.  
  17. =head1 SYNOPSIS
  18.  
  19.   use Module::Info;
  20.  
  21.   my $mod = Module::Info->new_from_file('Some/Module.pm');
  22.   my $mod = Module::Info->new_from_module('Some::Module');
  23.   my $mod = Module::Info->new_from_loaded('Some::Module');
  24.  
  25.   my @mods = Module::Info->all_installed('Some::Module');
  26.  
  27.   my $name    = $mod->name;
  28.   my $version = $mod->version;
  29.   my $dir     = $mod->inc_dir;
  30.   my $file    = $mod->file;
  31.   my $is_core = $mod->is_core;
  32.  
  33.   # Only available in perl 5.6.1 and up.
  34.   # These do compile the module.
  35.   my @packages = $mod->packages_inside;
  36.   my @used     = $mod->modules_used;
  37.   my @subs     = $mod->subroutines;
  38.   my @isa      = $mod->superclasses;
  39.   my @calls    = $mod->subroutines_called;
  40.  
  41.   # Check for constructs which make perl hard to predict.
  42.   my @methods   = $mod->dynamic_method_calls;
  43.   my @lines     = $mod->eval_string;    *UNIMPLEMENTED*
  44.   my @lines     = $mod->gotos;          *UNIMPLEMENTED*
  45.   my @controls  = $mod->exit_via_loop_control;      *UNIMPLEMENTED*
  46.   my @unpredictables = $mod->has_unpredictables;    *UNIMPLEMENTED*
  47.  
  48.   # set/get Module::Info options
  49.   $self->die_on_compilation_error(1);
  50.   my $die_on_error = $mod->die_on_compilation_error;
  51.  
  52. =head1 DESCRIPTION
  53.  
  54. Module::Info gives you information about Perl modules B<without
  55. actually loading the module>.  It actually isn't specific to modules
  56. and should work on any perl code.
  57.  
  58. =head1 METHODS
  59.  
  60. =head2 Constructors
  61.  
  62. There are a few ways to specify which module you want information for.
  63. They all return Module::Info objects.
  64.  
  65. =over 4
  66.  
  67. =item new_from_file
  68.  
  69.   my $module = Module::Info->new_from_file('path/to/Some/Module.pm');
  70.  
  71. Given a file, it will interpret this as the module you want
  72. information about.  You can also hand it a perl script.
  73.  
  74. If the file doesn't exist or isn't readable it will return false.
  75.  
  76. =cut
  77.  
  78. sub new_from_file {
  79.     my($proto, $file) = @_;
  80.     my($class) = ref $proto || $proto;
  81.  
  82.     return unless -r $file;
  83.  
  84.     my $self = {};
  85.     $self->{file} = File::Spec->rel2abs($file);
  86.     $self->{dir}  = '';
  87.     $self->{name} = '';
  88.  
  89.     return bless $self, $class;
  90. }
  91.  
  92. =item new_from_module
  93.  
  94.   my $module = Module::Info->new_from_module('Some::Module');
  95.   my $module = Module::Info->new_from_module('Some::Module', @INC);
  96.  
  97. Given a module name, @INC will be searched and the first module found
  98. used.  This is the same module that would be loaded if you just say
  99. C<use Some::Module>.
  100.  
  101. If you give your own @INC, that will be used to search instead.
  102.  
  103. =cut
  104.  
  105. sub new_from_module {
  106.     my($class, $module, @inc) = @_;
  107.     return ($class->_find_all_installed($module, 1, @inc))[0];
  108. }
  109.  
  110. =item new_from_loaded
  111.  
  112.   my $module = Module::Info->new_from_loaded('Some::Module');
  113.  
  114. Gets information about the currently loaded version of Some::Module.
  115. If it isn't loaded, returns false.
  116.  
  117. =cut
  118.  
  119. sub new_from_loaded {
  120.     my($class, $name) = @_;
  121.  
  122.     my $mod_file = join('/', split('::', $name)) . '.pm';
  123.     my $filepath = $INC{$mod_file} || '';
  124.  
  125.     my $module = Module::Info->new_from_file($filepath);
  126.     $module->{name} = $name;
  127.     ($module->{dir} = $filepath) =~ s|/?$mod_file$||;
  128.     $module->{dir} = File::Spec->rel2abs($module->{dir});
  129.  
  130.     return $module;
  131. }
  132.  
  133. =item all_installed
  134.  
  135.   my @modules = Module::Info->all_installed('Some::Module');
  136.   my @modules = Module::Info->all_installed('Some::Module', @INC);
  137.  
  138. Like new_from_module(), except I<all> modules in @INC will be
  139. returned, in the order they are found.  Thus $modules[0] is the one
  140. that would be loaded by C<use Some::Module>.
  141.  
  142. =cut
  143.  
  144. sub all_installed {
  145.     my($class, $module, @inc) = @_;
  146.     return $class->_find_all_installed($module, 0, @inc);
  147. }
  148.  
  149. # Thieved from Module::InstalledVersion
  150. sub _find_all_installed {
  151.     my($proto, $name, $find_first_one, @inc) = @_;
  152.     my($class) = ref $proto || $proto;
  153.  
  154.     @inc = @INC unless @inc;
  155.     my $file = File::Spec->catfile(split /::/, $name) . '.pm';
  156.     
  157.     my @modules = ();
  158.     DIR: foreach my $dir (@inc) {
  159.         # Skip the new code ref in @INC feature.
  160.         next if ref $dir;
  161.  
  162.         my $filename = File::Spec->catfile($dir, $file);
  163.         if( -r $filename ) {
  164.             my $module = $class->new_from_file($filename);
  165.             $module->{dir} = File::Spec->rel2abs($dir);
  166.             $module->{name} = $name;
  167.             push @modules, $module;
  168.             last DIR if $find_first_one;
  169.         }
  170.     }
  171.               
  172.     return @modules;
  173. }
  174.  
  175.  
  176. =back
  177.  
  178. =head2 Information without loading
  179.  
  180. The following methods get their information without actually compiling
  181. the module.
  182.  
  183. =over 4
  184.  
  185. =item B<name>
  186.  
  187.   my $name = $module->name;
  188.   $module->name($name);
  189.  
  190. Name of the module (ie. Some::Module).  
  191.  
  192. Module loaded using new_from_file() won't have this information in
  193. which case you can set it yourself.
  194.  
  195. =cut
  196.  
  197. sub name {
  198.     my($self) = shift;
  199.     
  200.     $self->{name} = shift if @_;
  201.     return $self->{name};
  202. }
  203.  
  204. =item B<version>
  205.  
  206.   my $version = $module->version;
  207.  
  208. Divines the value of $VERSION.  This uses the same method as
  209. ExtUtils::MakeMaker and all caveats therein apply.
  210.  
  211. =cut
  212.  
  213. # Thieved from ExtUtils::MM_Unix 1.12603
  214. sub version {
  215.     my($self) = shift;
  216.  
  217.     my $parsefile = $self->file;
  218.  
  219.     open(MOD, $parsefile) or die $!;
  220.  
  221.     my $inpod = 0;
  222.     my $result;
  223.     while (<MOD>) {
  224.         $inpod = /^=(?!cut)/ ? 1 : /^=cut/ ? 0 : $inpod;
  225.         next if $inpod || /^\s*#/;
  226.  
  227.         chomp;
  228.         next unless /([\$*])(([\w\:\']*)\bVERSION)\b.*\=/;
  229.         my $eval = qq{
  230.                       package Module::Info::_version;
  231.                       no strict;
  232.  
  233.                       local $1$2;
  234.                       \$$2=undef; do {
  235.                           $_
  236.                       }; \$$2
  237.         };
  238.         local $^W = 0;
  239.         $result = eval($eval);
  240.         warn "Could not eval '$eval' in $parsefile: $@" if $@;
  241.         $result = "undef" unless defined $result;
  242.         last;
  243.     }
  244.     close MOD;
  245.     return $result;
  246. }
  247.  
  248.  
  249. =item B<inc_dir>
  250.  
  251.   my $dir = $module->inc_dir;
  252.  
  253. Include directory in which this module was found.  Module::Info
  254. objects created with new_from_file() won't have this info.
  255.  
  256. =cut
  257.  
  258. sub inc_dir {
  259.     my($self) = shift;
  260.  
  261.     return $self->{dir};
  262. }
  263.  
  264. =item B<file>
  265.  
  266.   my $file = $module->file;
  267.  
  268. The absolute path to this module.
  269.  
  270. =cut
  271.  
  272. sub file {
  273.     my($self) = shift;
  274.  
  275.     return $self->{file};
  276. }
  277.  
  278. =item B<is_core>
  279.  
  280.   my $is_core = $module->is_core;
  281.  
  282. Checks if this module is the one distributed with Perl.
  283.  
  284. B<NOTE> This goes by what directory it's in.  It's possible that the
  285. module has been altered or upgraded from CPAN since the original Perl
  286. installation.
  287.  
  288. =cut
  289.  
  290. sub is_core {
  291.     my($self) = shift;
  292.  
  293.     return scalar grep $self->{dir} eq File::Spec->canonpath($_), 
  294.                            ($Config{installarchlib},
  295.                             $Config{installprivlib});
  296. }
  297.  
  298. =back
  299.  
  300. =head2 Information that requires loading.
  301.  
  302. B<WARNING!>  From here down reliability drops rapidly!
  303.  
  304. The following methods get their information by compiling the module
  305. and examining the opcode tree.  The module will be compiled in a
  306. seperate process so as not to disturb the current program.
  307.  
  308. They will only work on 5.6.1 and up and requires the B::Utils module.
  309.  
  310. =over 4
  311.  
  312. =item B<packages_inside>
  313.  
  314.   my @packages = $module->packages_inside;
  315.  
  316. Looks for any explicit C<package> declarations inside the module and
  317. returns a list.  Useful for finding hidden classes and functionality
  318. (like Tie::StdHandle inside Tie::Handle).
  319.  
  320. B<KNOWN BUG> Currently doesn't spot package changes inside subroutines.
  321.  
  322. =cut
  323.  
  324. sub packages_inside {
  325.     my $self = shift;
  326.  
  327.     my %packs = map {$_, 1} $self->_call_B('packages');
  328.     return keys %packs;
  329. }
  330.  
  331. =item B<package_versions>
  332.  
  333.   my %versions = $module->package_versions;
  334.  
  335. Returns a hash whose keys are the packages contained in the module
  336. (these are the same as what's returned by C<packages_inside()>), and
  337. whose values are the versions of those packages.
  338.  
  339. =cut
  340.  
  341. sub package_versions {
  342.     my $self = shift;
  343.  
  344.     my @packs = $self->packages_inside;
  345.  
  346.     # To survive the print(), we translate undef into '~' and then back again.
  347.     (my $quoted_file = $self->file) =~ s/(['\\])/\\$1/g;
  348.     my $command = qq{-le "require '$quoted_file';};
  349.     foreach (@packs) {
  350.         $command .= " print defined $_->VERSION ? $_->VERSION : '~';"
  351.     }
  352.     $command .= qq{"};
  353.  
  354.     my ($status, @versions) = $self->_call_perl($command);
  355.     chomp @versions;
  356.     foreach (@versions) {
  357.         $_ = undef if $_ eq '~';
  358.     }
  359.  
  360.     my %map;
  361.     @map{@packs} = @versions;
  362.  
  363.     return %map;
  364. }
  365.  
  366.  
  367. =item B<modules_used>
  368.  
  369.   my @used = $module->modules_used;
  370.  
  371. Returns a list of all modules and files which may be C<use>'d or
  372. C<require>'d by this module.
  373.  
  374. B<NOTE> These modules may be conditionally loaded, can't tell.  Also
  375. can't find modules which might be used inside an C<eval>.
  376.  
  377. =cut
  378.  
  379. sub modules_used {
  380.     my($self) = shift;
  381.  
  382.     my $mod_file = $self->file;
  383.     my @mods = $self->_call_B('modules_used');
  384.  
  385.     my @used_mods = ();
  386.     push @used_mods, map { my($file) = /^use (\S+)/;  _file2mod($file); }
  387.                      grep /^use \D/ && /at \Q$mod_file\E /, @mods;
  388.  
  389.     push @used_mods, map { my($file) = /^require bare (\S+)/;  _file2mod($file) }
  390.                      grep /^require bare \D/ , @mods;
  391.  
  392.     push @used_mods, map { /^require not bare (\S+)/; $1 } 
  393.                      grep /^require not bare \D/, @mods;
  394.  
  395.     my %used_mods = ();
  396.     @used_mods{@used_mods} = (1) x @used_mods;
  397.     return keys %used_mods;
  398. }
  399.  
  400. sub _file2mod {
  401.     my($mod) = shift;
  402.     $mod =~ s/\.pm//;
  403.     $mod =~ s|/|::|g;
  404.     return $mod;
  405. }
  406.  
  407.  
  408. =item B<subroutines>
  409.  
  410.   my %subs = $module->subroutines;
  411.  
  412. Returns a hash of all subroutines defined inside this module and some
  413. info about it.  The key is the *full* name of the subroutine
  414. (ie. $subs{'Some::Module::foo'} rather than just $subs{'foo'}), value
  415. is a hash ref with information about the subroutine like so:
  416.  
  417.     start   => line number of the first statement in the subroutine
  418.     end     => line number of the last statement in the subroutine
  419.  
  420. Note that the line numbers may not be entirely accurate and will
  421. change as perl's backend compiler improves.  They typically correspond
  422. to the first and last I<run-time> statements in a subroutine.  For
  423. example:
  424.  
  425.     sub foo {
  426.         package Wibble;
  427.         $foo = "bar";
  428.         return $foo;
  429.     }
  430.  
  431. Taking C<sub foo {> as line 1, Module::Info will report line 3 as the
  432. start and line 4 as the end.  C<package Wibble;> is a compile-time
  433. statement.  Again, this will change as perl changes.
  434.  
  435. Note this only catches simple C<sub foo {...}> subroutine
  436. declarations.  Anonymous, autoloaded or eval'd subroutines are not
  437. listed.
  438.  
  439. =cut
  440.  
  441. sub subroutines {
  442.     my($self) = shift;
  443.  
  444.     my $mod_file = $self->file;
  445.     my @subs = $self->_call_B('subroutines');
  446.     return  map { /^(\S+) at \S+ from (\d+) to (\d+)/; 
  447.                   ($1 => { start => $2, end => $3 }) } 
  448.             grep /at \Q$mod_file\E /, @subs;
  449. }
  450.  
  451. sub _is_win95() {
  452.     return $^O eq 'MSWin32' && Win32::GetOSVersion() == 1;
  453. }
  454.  
  455. sub _is_macos_classic() {
  456.     return $^O eq 'MacOS';
  457. }
  458.  
  459. sub _get_extra_arguments { '' }
  460.  
  461. sub _call_perl {
  462.     my($self, $args) = @_;
  463.  
  464.     my $perl = _is_macos_classic ? 'perl' : $^X;
  465.     my $command = "$perl $args";
  466.     my @out;
  467.  
  468.     if( _is_win95 ) {
  469.         require IPC::Open3;
  470.         local *OUTFH;
  471.         my($line, $in);
  472.         my $out = \*OUTFH;
  473.         my $pid = IPC::Open3::open3($in, $out, $out, $command);
  474.         close $in;
  475.         while( defined($line = <OUTFH>) ) {
  476.             $line =~ s/\r\n$/\n/; # strip CRs
  477.             push @out, $line;
  478.         }
  479.  
  480.         waitpid $pid, 0;
  481.     }
  482.     elsif( _is_macos_classic ) {
  483.         @out = `$command \xb7 Dev:Stdout`;
  484.     }
  485.     else {
  486.         @out = `$command 2>&1`;
  487.     }
  488.  
  489.     @out = grep !/^Using.*blib$/, @out;
  490.     return ($?, @out);
  491. }
  492.  
  493. sub _call_B {
  494.     my($self, $arg) = @_;
  495.  
  496.     my $mod_file = $self->file;
  497.     my $extra_args = $self->_get_extra_arguments;
  498.     my $command = qq{$extra_args "-MO=Module::Info,$arg" "$mod_file"};
  499.     my($status, @out) = $self->_call_perl($command);
  500.  
  501.     if( $status ) {
  502.         my $exit = $status >> 8;
  503.         my $msg = join "\n",
  504.                        "B::Module::Info,$arg use failed with $exit saying:",
  505.                        @out;
  506.  
  507.         if( $self->{die_on_compilation_error} ) {
  508.             die $msg;
  509.         }
  510.         else {
  511.             warn $msg;
  512.             return;
  513.         }
  514.     }
  515.  
  516.     @out = grep !/syntax OK$/, @out;
  517.     chomp @out;
  518.     return @out;
  519. }
  520.  
  521.  
  522. =item B<superclasses>
  523.  
  524.   my @isa = $module->superclasses;
  525.  
  526. Returns the value of @ISA for this $module.  Requires that
  527. $module->name be set to work.
  528.  
  529. B<NOTE> superclasses() is currently cheating.  See L<CAVEATS> below.
  530.  
  531. =cut
  532.  
  533. sub superclasses {
  534.     my $self = shift;
  535.  
  536.     my $mod_file = $self->file;
  537.     my $mod_name = $self->name;
  538.     unless( $mod_name ) {
  539.         carp 'isa() requires $module->name to be set';
  540.         return;
  541.     }
  542.  
  543.     my $extra_args = $self->_get_extra_arguments;
  544.     my $command =
  545.       qq{-e "require q{$mod_file}; print join qq{\\n}, \@$mod_name\::ISA"};
  546.     my($status, @isa) = $self->_call_perl("$extra_args $command");
  547.     chomp @isa;
  548.     return @isa;
  549. }
  550.  
  551. =item B<subroutines_called>
  552.  
  553.   my @calls = $module->subroutines_called;
  554.  
  555. Finds all the methods and functions which are called inside the
  556. $module.
  557.  
  558. Returns a list of hashes.  Each hash represents a single function or
  559. method call and has the keys:
  560.  
  561.     line        line number where this call originated
  562.     class       class called on if its a class method
  563.     type        function, symbolic function, object method, 
  564.                 class method, dynamic object method or 
  565.                 dynamic class method.
  566.                 (NOTE  This format will probably change)
  567.     name        name of the function/method called if not dynamic
  568.  
  569.  
  570. =cut
  571.  
  572. sub subroutines_called {
  573.     my($self) = shift;
  574.  
  575.     my @subs = $self->_call_B('subs_called');
  576.     my $mod_file = $self->file;
  577.  
  578.     @subs = grep /at \Q$mod_file\E line/, @subs;
  579.     my @out = ();
  580.     foreach (@subs) {
  581.         my %info = ();
  582.         ($info{type}) = /^(.+) call/;
  583.         $info{type} = 'symbolic function' if /using symbolic ref/;
  584.         ($info{'name'}) = /to (\S+)/;
  585.         ($info{class})= /via (\S+)/;
  586.         ($info{line}) = /line (\d+)/;
  587.         push @out, \%info;
  588.     }
  589.     return @out;
  590. }
  591.  
  592. =back
  593.  
  594. =head2 Information about Unpredictable Constructs
  595.  
  596. Unpredictable constructs are things that make a Perl program hard to
  597. predict what its going to do without actually running it.  There's
  598. nothing wrong with these constructs, but its nice to know where they
  599. are when maintaining a piece of code.
  600.  
  601. =over 4
  602.  
  603. =item B<dynamic_method_calls>
  604.  
  605.   my @methods = $module->dynamic_method_calls;
  606.  
  607. Returns a list of dynamic method calls (ie. C<$obj->$method()>) used
  608. by the $module.  @methods has the same format as the return value of
  609. subroutines_called().
  610.  
  611. =cut
  612.  
  613. sub dynamic_method_calls {
  614.     my($self) = shift;
  615.     return grep $_->{type} =~ /dynamic/, $self->subroutines_called;
  616. }
  617.  
  618. =back
  619.  
  620. =head2 Options
  621.  
  622. The following methods get/set specific option values for the
  623. Module::Info object.
  624.  
  625. =over 4
  626.  
  627. =item B<die_on_compilation_error>
  628.  
  629.   $module->die_on_compilation_error(0); # default
  630.   $module->die_on_compilation_error(1);
  631.   my $flag = $module->die_on_compilation_error;
  632.  
  633. Sets/gets the "die on compilation error" flag. Whne the flag is off
  634. (default), and a module fails to compile, Module::Info simply emits a
  635. watning and continues. When the flag is on and a module fails to
  636. compile, Module::Info die()s with the same error message it would use
  637. in the warning.
  638.  
  639. =cut
  640.  
  641. sub die_on_compilation_error {
  642.     my($self) = shift;
  643.  
  644.     $self->{die_on_compilation_error} = $_[0] ? 1 : 0 if @_;
  645.     return $self->{die_on_compilation_error};
  646. }
  647.  
  648. =back
  649.  
  650. =head1 AUTHOR
  651.  
  652. Michael G Schwern <schwern@pobox.com> with code from ExtUtils::MM_Unix,
  653. Module::InstalledVersion and lots of cargo-culting from B::Deparse.
  654.  
  655. Mattia Barbon <MBARBON@cpan.org> is the current maintainer.
  656.  
  657. =head1 THANKS
  658.  
  659. Many thanks to Simon Cozens and Robin Houston for letting me chew
  660. their ears about B.
  661.  
  662. =head1 CAVEATS
  663.  
  664. Code refs in @INC are currently ignored.  If this bothers you submit a
  665. patch.
  666.  
  667. superclasses() is cheating and just loading the module in a seperate
  668. process and looking at @ISA.  I don't think its worth the trouble to
  669. go through and parse the opcode tree as it still requires loading the
  670. module and running all the BEGIN blocks.  Patches welcome.
  671.  
  672. I originally was going to call superclasses() isa() but then I
  673. remembered that would be bad.
  674.  
  675. All the methods that require loading are really inefficient as they're
  676. not caching anything.  I'll worry about efficiency later.
  677.  
  678. =cut
  679.  
  680. return 'Stepping on toes is what Schwerns do best!  *poing poing poing*';
  681.