This is like which for perl modules. It will search through your @INC path, and find all matches for a specified module name.
With no arguments it will print out all modules in all paths, with a description.
EDIT: Some (shorter/better) alternatives have been posted here:
whichpm.
Examples:
perlwhich -m <string>
greps for <string> in the title of all your perl modules.
perlwhich -m -e Module::FullName
finds an exact match for that module name.
perlwhich
prints all modules with a description.
BUGS: Doesn't strip platform off some of the include paths.
#!/util/bin/perl -w
# perlwhich
## code started as:
# pmdesc - describe pm files
# tchrist --@-- perl.com
## from perlcookbook
## modified 2003 by jmanning2k
use strict;
use File::Find qw(find);
use Getopt::Std qw(getopts);
use Carp;
use vars (
q!$opt_v!, # give debug info
q!$opt_w!, # warn about missing descs on modules
q!$opt_a!, # include relative paths
q!$opt_s!, # sort output within each directory
q!$opt_m!, # Look at one particular module.
q!$opt_e!, # Exact matches only with opt_m
q!$opt_i!, # Case insensitive
);
$| = 1;
getopts('iwvasem:') or die "bad usage";
@ARGV = @INC unless @ARGV;
# Globals. wish I didn't really have to do this.
use vars (
q!$Start_Dir!, # The top directory find was called with
q!%Future!, # topdirs find will handle later
);
my $Module;
# install an output filter to sort my module list, if wanted.
if ($opt_s) {
if (open(ME, "-|")) {
$/ = '';
while (<ME>) {
chomp;
print join("\n", sort split /\n/), "\n";
}
exit;
}
}
MAIN: {
my %visited;
my ($dev,$ino);
@Future{@ARGV} = (1) x @ARGV;
foreach $Start_Dir (@ARGV) {
delete $Future{$Start_Dir};
$Start_Dir =~ s {/$}{}; ## strip final slash
print "\n<<Modules from $Start_Dir>>\n\n"
if $opt_v;
next unless ($dev,$ino) = stat($Start_Dir);
next if $visited{$dev,$ino}++;
next unless $opt_a || $Start_Dir =~ m!^/!;
find(\&wanted, $Start_Dir);
}
exit;
}
# calculate module name from file and directory
sub modname {
local $_ = $File::Find::name;
#print "Start $_\n" if $opt_v;
if (index($_, $Start_Dir . '/') == 0) {
substr($_, 0, 1+length($Start_Dir)) = '';
}
s { / } {::}gx; # replace slash with ::
s { \.p(m|od)$ } {}x; # strip pm or pod from end
#print "Got $_\n" if $opt_v;
return $_;
}
# decide if this is a module we want
sub wanted {
if ( $Future{$File::Find::name} ) {
warn "\t(Skipping $File::Find::name, qui venit in futuro.)\n"
if 0 and $opt_v;
$File::Find::prune = 1;
return;
}
return unless /\.pm$/ && -f;
$Module = &modname;
if($opt_m) {
if($opt_i) {
return unless($Module =~ /$opt_m/i);
} else {
return unless($Module =~ /$opt_m/);
}
return unless(!$opt_e || $Module eq $opt_m);
}
# skip obnoxious modules
if ($Module =~ /^CPAN(\Z|::)/) {
warn("$Module -- skipping because it misbehaves\n");
return;
}
my $file = $_;
unless (open(POD, "< $file")) {
warn "\tcannot open $file: $!";
# if $opt_w;
return 0;
}
if($opt_m) {
print "$Start_Dir -- ";
}
$: = " -:";
local $/ = '';
local $_;
while (<POD>) {
if (/=head\d\s+NAME/) {
chomp($_ = <POD>);
s/^.*?-\s+//s;
s/\n/ /g;
#write;
my $v;
if (defined ($v = getversion($Module))) {
print "$Module ($v) ";
} else {
print "$Module ";
}
print "- $_\n";
return 1;
}
}
print "$Module\n";
warn "\t(MISSING DESC FOR $File::Find::name)\n"
if $opt_w;
return 0;
}
# run Perl to load the module and print its verson number, redirecting
# errors to /dev/null
sub getversion {
my $mod = shift;
my $vers = `$^X -m$mod -e 'print \$${mod}::VERSION' 2>/dev/null`;
$vers =~ s/^\s*(.*?)\s*$/$1/; # remove stray whitespace
return ($vers || undef);
}
format =
^<<<<<<<<<<<<<<<<<~~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+<<<<<<
$Module, $_
.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.