5

Is there a smart way to detect whether a certain Perl module has been installed in your system? My old sutpid way is to write a Perl script in which the only thing I do is just to use the module. If nothing croaks when I run the detect script, then I know the module has been installed, although I still don't know which version and where the module has been installed .

thanks in advance.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Haiyuan Zhang
  • 40,802
  • 41
  • 107
  • 134
  • 1
    See also http://stackoverflow.com/questions/135755/how-can-i-find-the-version-of-an-installed-perl-module – Ether Dec 29 '09 at 01:01

9 Answers9

10

Something like:

perl -MModule -e 'print "$Module::VERSION\n"' 2>/dev/null || echo "Not installed"

would give you the version of a given module, or tell you it isn't installed. Usage would look like:

perl -MXML::Parser -e 'print "$XML::Parser::VERSION\n"' 2>/dev/null || echo "Not installed"

To find the module path, you could examine @INC to find possible locations, or you could perhaps look into perlwhich. There is also pmpath from pmtools.

DMI
  • 6,843
  • 2
  • 24
  • 25
  • 6
    if you're using pmtools, then [pminst](http://search.cpan.org/~mlfisher/pmtools/pminst) shows if a module is installed, and [pmvers](http://search.cpan.org/~mlfisher/pmtools/pmvers) shows which version is installed. ('apt-get install pmtools' on Debian/Ubuntu) – plusplus Dec 17 '09 at 09:22
6

The shortest thing I know of that doesn't involve a script or shell alias:

$ perl -MFoo::Bar\ 99
Foo::Bar version 99 required--this is only version 1.234.

(or the usual message about not being in @INC if it's not installed)

For the curious, this is the same as perl -e 'use Foo::Bar 99'.

hdp
  • 778
  • 3
  • 6
3

instmodsh

NAME
       instmodsh - A shell to examine installed modules

SYNOPSIS
           instmodsh

DESCRIPTION
       A little interface to ExtUtils::Installed to examine installed modules, validate your packlists and even create a tarball from an installed module.

SEE ALSO
       ExtUtils::Installed
Gregory Pakosz
  • 69,011
  • 20
  • 139
  • 164
  • Good to know, but note that _core_ modules are not listed separately, but rather as files belonging to an abstract module simply named 'Perl'. Aside from that, the fact that `instmodsh` is a _shell_ makes it bit awkward to use - you need multiple interactive steps to get the desired information, and while I could find the _location_ of a module, there seems to be no way to get the _version_. On the flip side, using the `l` command is a convenient way to see all non-core modules (which may have come with a particular distribution or may have been user-installed later). – mklement0 Sep 02 '15 at 17:35
  • Another consideration: `instmodsh` won't find modules that weren't installed via `*.packlist` files. – mklement0 Sep 02 '15 at 18:12
3

Here's a program which does that:

#!/usr/bin/perl
# testmod - test to see if a module is available

use strict;
use warnings;

my $mod = (shift @ARGV) || die "usage: $0 module\n";

# convert module-name to path
my $file = $mod;
$file =~ s{::}{/}gsmx;
$file .= '.pm';

# Pull in the module, if it exists
eval { require $file }
    or die "can't find module $mod\n";

# Get the version from the module, if defined
my $ver;
{ no strict 'refs';
    $ver = ${$mod . "::VERSION"} || 'UNKNOWN';
}
# And its location
my $from = $INC{$file};
print "module $mod is version $ver loaded from $from\n";
Colin Pickard
  • 45,724
  • 13
  • 98
  • 148
2

Use pmvers. Like the name suggests, it shows the version of an installed module. If a module is not installed, it fails with the familiar error message: Can't locate … in @INC (@INC contains: …)

Use pmpath from the same distribution to find a module's installation path.

daxim
  • 39,270
  • 4
  • 65
  • 132
1

I don't know if there is any smart way for this. But what I usually
do is to make use of '-l' or '-m' option of perldoc. For example :

%perldoc -l XML::Simple

and the output is something like below,which is the full path of module file

.../lib/XML/Simple.pm

The advantage with this approach compared to yours is that, if the module is installed
the output contains the path for module location. However when the module is not installed
or if it doesn't has a perldoc the error message shown is "No documentation found for ...",
making it impossible to distinguish if the error is due to missing module or missing
documentation. In such scenario the -m option becomes handy since it prints entire
contents of the file along with the path.

sateesh
  • 27,947
  • 7
  • 36
  • 45
  • 1
    perldoc is not generally suitable because it deals with a module's documentation which can be sometimes separate from the code, e.g. XML::LibXML::Document. – daxim Dec 18 '09 at 13:30
  • I don't get your concern here. If you can plesae ealborate why this would be unsuitable it would be helpful. As per -help option of the perldoc : -m Display module's file in its entirety -l Display the module's file name So perldoc essentily can handle the module files In the above case XML/LibXML/Document.pod is a pod file not a .pm file. Even an attempt like %perl -e 'use XML::LibXML::Document' gives an error. – sateesh Dec 18 '09 at 13:42
  • `perldoc -ml XML::LibXML::Document` gives you the path to the `.pm` file even if there's a separate `.pod` file. – hdp Dec 18 '09 at 15:49
  • 2
    sateesh, perldoc cannot give you the file where the code of the package XML::LibXML::Document is installed, namely XML/LibXML.pm. That XML/LibXML/Document.pod is a pod file is not the point. hdp, this your claim is false. Try it out: »No module found for "XML::LibXML::Document".« – daxim Dec 20 '09 at 13:06
  • daxim, thanks for your explanation. It makes clear to me that perldoc cannot be always relied upon to get location of installed perl module. – sateesh Dec 23 '09 at 03:56
1

I use these bash function/Perl oneliners to find the version number and location of Perl modules:

# equivalent to perldoc -l <module>
perlwhere() {
    perl -wle'eval "require $ARGV[0]" or die; ($mod = $ARGV[0]) =~ s|::|/|g; print $INC{"${mod}.pm"}' $1
}

perlversion() {
    perl -M$1 -wle'print $ARGV[0]->VERSION' $1
}

: [ether ~].2$; perlwhere Test::More
/usr/lib/perl5/5.8.8/Test/More.pm
: [ether ~].2$; perlversion Test::More
0.94
Ether
  • 53,118
  • 13
  • 86
  • 159
1

The pmvers utility and the other pmtools will do what you need. Otherwise here is a one-liner to find a module version:

perl -le 'eval "require $ARGV[0]" and print $ARGV[0]->VERSION' Some::Module
mklement0
  • 382,024
  • 64
  • 607
  • 775
jmcnamara
  • 38,196
  • 6
  • 90
  • 108
  • Nice, though I suggest the following minor tweak so as to be able to distinguish a non-existent module from one that happens not to have a version number: `perl -le 'eval "require $ARGV[0]" or die; print $ARGV[0]->VERSION' Some::Module` – mklement0 Sep 02 '15 at 18:03
0

If you're looking for a cross-platform CLI (Linux, OSX, Windows), consider my whichpm utility; e.g.:

# Locate the Data::Dumper module, and also print
# version information and core-module status.
$ whichpm -v Data::Dumper
Data::Dumper    2.145   core>=5.005 /usr/lib/perl/5.18/Data/Dumper.pm

It can also find accidental duplicates and list all installed modules.

If you happen to have Node.js / io.js installed, you can install it from the npm registry:

[sudo] npm install whichpm -g

For manual installation instructions and more, see the repo; here's a direct download link to the latest version (will stay current).

mklement0
  • 382,024
  • 64
  • 607
  • 775