Symkat

Bloggity Blog

Find a Perl Module's Path

Posted in Programming

Articles for Programming

Perl is an awesome language, made better by the huge assortment of modules available to extend the language. With modules to serve as everything from database abstraction layers and ORMs to HTTP Client libraries you can often quickly implement projects. Not every module is created perfectly and you may want to review the code you're loading into your project, identify bugs or generally poke around.

While multiple versions of a given module may be installed, finding the version you're using is rather simple if you let Perl itself tell you.

Finding A Perl Module's Path

@INC and %INC provide data related to modules. @INC is an array of the paths for which Perl will locate a module's source and load it into the program. %INC is a hash and contains the module name as a key, and the file it was loaded from as the value. It is worth noting that the module name is written in file-system style (This/That.pm) style as opposed to package-name style (This::That).

Finding the path that a given module is loaded from is as simple as loading the module and asking for the contains of %INC:

$ perl -MList::Util -e'print $_ . " => " . $INC{$_} . "\n" for keys %INC'

-MList::Util translates into a use List::Util for the Perl one liner. If you wanted to know the path to LWP instead, you could use -MLWP just as easily.

Running the above command we get:

$ perl -MList::Util -e'print $_ . " => " . $INC{$_} . "\n" for keys %INC'
XSLoader.pm => /usr/lib/perl/5.10/XSLoader.pm
warnings.pm => /usr/share/perl/5.10/warnings.pm
warnings/register.pm => /usr/share/perl/5.10/warnings/register.pm
Exporter.pm => /usr/share/perl/5.10/Exporter.pm
vars.pm => /usr/share/perl/5.10/vars.pm
strict.pm => /usr/share/perl/5.10/strict.pm
List/Util.pm => /usr/lib/perl/5.10/List/Util.pm

We now know that the file which is loaded for List::Util is /usr/lib/perl/5.10/List/Util.pm. If the amount of information in %INC is too much for you, you could instead ask for only the path to the Perl module which you want to know:

$ perl -MList::Util -e'print $INC{"List/Util.pm"} . "\n"'
/usr/lib/perl/5.10/List/Util.pm

We can of course write a tiny script to make this even more trivial.

#!/usr/bin/perl
use warnings;
use strict;

for my $module ( @ARGV ) {
    my $package = $module;

    # From This::That to This/That.pm
    s/::/\//g, s/$/.pm/ for $module;

    if ( require $module ) {
        print $package . " => " . $INC{$module} . "\n";
    }
}

And then pass the modules we want to know about to it:

$ ./fpm.pl List::Util DBI  
List::Util => /usr/lib/perl/5.10/List/Util.pm
DBI => /usr/lib/perl5/DBI.pm

Using Perldoc To Find Perl Module's Paths

Knowing how to find the path with Perl itself is immensely useful, though, a slightly simpler method is to use perldoc if it is installed.

$ perldoc -lm List::Util
/usr/lib/perl/5.10/List/Util.pm

The -l switch instructs perldoc to display the path for the file, instead of the POD itself. The -m switch instructs perldoc to display the entire file for a given module, even if it doesn't have a POD.

The -m switch is important, as if the module does not have a POD associated with it, failing to use the -m switch is the difference between getting the path for the file and being told there is no documentation found.

While there are a number of methods to find this information, these are among the most simple and least error prone methods to identify the path to a Perl module you're using. What's your recommended method?

blog comments powered by Disqus