tags:

views:

243

answers:

8

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.

+8  A: 

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.

Dave
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
+2  A: 

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
+1  A: 
sateesh
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
I don't get your concern here. If you can plesae ealborate why thiswould 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 nameSo perldoc essentily can handle the module filesIn 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
`perldoc -ml XML::LibXML::Document` gives you the path to the `.pm` file even if there's a separate `.pod` file.
hdp
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
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
+1  A: 

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
A: 

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
A: 

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
jmcnamara
+3  A: 

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
`cpan -D Foo::Bar` is slightly shorter. :)
brian d foy
A: 

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

Thomas Erskine