Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

perlwhich - find which perl module you are using (and more)

by jmanning2k (Pilgrim)
on Jul 18, 2003 at 18:05 UTC ( #275693=snippet: print w/replies, xml ) Need Help??
Description: 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.

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 --@--
## 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>) {
            print join("\n", sort split /\n/), "\n";

  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);

# 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 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");

    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/\n/ /g;
    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,        $_
Replies are listed 'Best First'.
Re: perlwhich - find which perl module you are using (and more)
by bsb (Priest) on Jul 24, 2003 at 05:17 UTC
    $ pmpath CGI /usr/share/perl/5.6.1/
    pmpath from pmtools will extract the version by searching @INC for you.
    There's other handy stuff in there
    $ man -k pm | g 1p pmall (1p) - show all installed versions and descs pman (1p) - show a module's man page pmcat (1p) - page through a module file pmdesc (1p) - print out version and whatis description of per +l modules pmdirs (1p) - print out module directories pmexp (1p) - show a module's exports pmfunc (1p) - cat out a function from a module pminst (1p) - find modules whose names match this pattern pmload (1p) - show what files a given module loads at compile + time pmls (1p) - long list the module path pmpath (1p) - show full path to a perl module pmvers (1p) - print out a module's version
Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://275693]
[moritz]: seems there's a size limit for hostenum, and the error message just sucks
[vrk]: None, other than the location of the error: auto/NetAddr/IP/
[vrk]: Aha, there's a reference to "bug report 82719" in NetAddr/'s sub _splitref.
[moritz]: wow, that's their idea of an "improved error message"

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (9)
As of 2017-04-25 07:39 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (449 votes). Check out past polls.