Reputation: 8536
in Perl, when I do use <module name> <ver>;
, the system finds the .pm
file for the library somewhere in the @INC
path.
Is there a reliable way to which file was actually loaded?
Upvotes: 48
Views: 27102
Reputation: 3249
I use the shell script /usr/local/bin/which_perl_module
#!/bin/sh
if [ ! $1 ];then echo "Which perl module should I look for?"; exit; fi
echo -n "You are using: "
perldoc -l $1
echo "which I found by looking in:"
perl -MData::Dump=pp -e 'unshift @INC, '$1'; pp(\@INC)'
Upvotes: 0
Reputation: 2412
You can use the instmodsh command: http://perldoc.perl.org/instmodsh.html.
Upvotes: 0
Reputation: 51137
Yes, %INC
contains the full path a module was loaded from.
Example:
$ perl -M'Data::Dump qw(pp)' -e 'pp(\%INC)'
{
"Data/Dump.pm" => "/usr/share/perl5/Data/Dump.pm",
"Exporter.pm" => "/usr/share/perl/5.10/Exporter.pm",
"List/Util.pm" => "/usr/lib/perl/5.10/List/Util.pm",
"Scalar/Util.pm" => "/usr/lib/perl/5.10/Scalar/Util.pm",
"XSLoader.pm" => "/usr/lib/perl/5.10/XSLoader.pm",
"overload.pm" => "/usr/share/perl/5.10/overload.pm",
"strict.pm" => "/usr/share/perl/5.10/strict.pm",
"vars.pm" => "/usr/share/perl/5.10/vars.pm",
"warnings.pm" => "/usr/share/perl/5.10/warnings.pm",
"warnings/register.pm" => "/usr/share/perl/5.10/warnings/register.pm",
}
Upvotes: 71
Reputation: 91
perl -M'LWP' -e 'use Data::Dumper; print Dumper \%INC' | grep LWP
This will list out the LWP module location on the disk and also lists out modules loaded inside LWP.
'LWP.pm' => '/usr/lib/perl5/5.10.0/LWP.pm',
'LWP/Protocol.pm' => '/usr/lib/perl5/5.10.0/LWP/Protocol.pm',
'LWP/UserAgent.pm' => '/usr/lib/perl5/5.10.0/LWP/UserAgent.pm',
Upvotes: 9
Reputation: 51
Here is a one-liner (with a bash wrapper) to determine if a module is installed - and where it will be loaded from:
#!/bin/bash
perl -M${1} -le "\$mname=\"${1}.pm\";\$mname=~s#::#/#g;print \"$1 INSTALLED AT \$INC{\$mname}\";" 2>/dev/null || echo "${1} NOT INSTALLED"
Call it with perl's module name syntax:
./find_perl_module Font::Metrics::Courier
Upvotes: 5
Reputation: 102713
If the module has pod documentation, and if you can guarantee that the perldoc utility in your PATH belongs to the same perl that is running your script, then this command will often give you the actual file being found:
perldoc -l ModuleName
Upvotes: 9
Reputation: 132719
You want to look in the %INC
variable, which records the filename it loaded for the libraries you load with do
, require
, or use
. See perlvar for the details.
Upvotes: 7
Reputation: 2061
Module::Mapper provides a way to walk the @INC tree to find modules:
perl -MModule::Mapper -MData::Dumper \
-e 'print Dumper( find_sources( UseINC => 1, Modules => [ @ARGV ] ) )' \
list-of-modules-to-locate
Upvotes: 1
Reputation: 1183
There are a good number of modules in CPAN for finding this information, the most likely candidates look to be Module::Find, Module::Which, and Module::Locate. I'd probably go with Module::Locate:
use strict;
use warnings;
use Module::Locate qw/locate/;
my $to_find = "Some::Module";
print "Perl would use: ", scalar locate($to_find), "\n";
In list context locate returns all found copies of Some::Module in order based on @INC.
Edit: derobert suggests a much better way, I didn't realize %INC already had it... This module based solution would still be useful if you wanted to know before loading the module where it was going to be loaded from.
Upvotes: 5
Reputation: 16007
From what I found, perl will look in the directories within the path:
perl -le 'print foreach @INC'
Then it will look in the standard library, and then in the current directory.
That gives you a search order.
My source:
Upvotes: 2