12

I'm writing a small Perl script that depends on some modules that might be available, so during the installation I would have to check if everythings there. I could just write use some::module and see if an error comes up, but a short message like "You need to install some::module" would be more helpful for endusers.

I also could just search every directory in @INC, but as it's Perl, there has to be an easier way.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
tstenner
  • 10,080
  • 10
  • 57
  • 92
  • 1
    How to check whether a perl module is installed isn't a question, it is a statement. – cjk Apr 29 '09 at 12:27

5 Answers5

22
perl -MSome::Module -e ';'

Whoops, misread the question. I thought you wanted to know in a one-off instance, not discovering it in a recoverable manner. I always use something like this:

sub try_load {
  my $mod = shift;

  eval("use $mod");

  if ($@) {
    #print "\$@ = $@\n";
    return(0);
  } else {
    return(1);
  }
}

Which you use like this:

$module = 'Some::Module';
if (try_load($module)) {
  print "loaded\n";
} else {
  print "not loaded\n";
}
jj33
  • 7,543
  • 2
  • 38
  • 42
  • 1
    Want to note here that the eval is doing double duty: it's allowing you to check for an arbitrary module, and it's preventing the use statement from getting turned into a BEGIN block. Upshot is, if you were to write code like this but hardcoded for a specific module, you'd still use the string-based eval. – chaos Apr 29 '09 at 19:09
  • 1
    I liked your answer, since I want to figure this out from bash, however, I get in trouble with modules needing an argument. e.g. [jens@ca60c173 (perl) p]$ perl -MPackage::DeprecationManager -e ';' You must provide a hash reference -deprecations parameter when importing Package::DeprecationManager at -e line 0. – Jens Timmerman Apr 05 '13 at 08:38
  • A quick comment that, although this is good, it would not work for inline module. – Jacques Dec 03 '21 at 01:39
4

How about:

die "Some::Module missing!" unless(eval{require Some::Module});
heeen
  • 4,736
  • 2
  • 21
  • 24
  • 1
    You need to call import if you are going to mimic use and adding a one at the end is a good idea since import is not required to return a true value: eval{require Some::Module; Some::Module->import; 1}; This will also not be enough if the module is lexical in nature (like autobox) since it will import in the eval then go out of scope when the eval ends. – Chas. Owens Apr 29 '09 at 13:57
2

I have a little script that lists all the Perl modules on my system;

#!/usr/bin/perl

use ExtUtils::Installed;
my $instmod = ExtUtils::Installed->new();
foreach my $module ($instmod->modules()) {
    my $version = $instmod->version($module) || "???";
    print "$module -- $version\n";
}

Inside that foreach loop you might want to do some thing like;

my $match;
if ($module =~ /$match/) {
  print "Found $match: $module\n";
}
brian d foy
  • 129,424
  • 31
  • 207
  • 592
jeremiah
  • 844
  • 9
  • 15
1

I use something like this:

BEGIN { 
    my $module_name    = shift; # @ARGV
    our $module_exp = $module_name;
    eval "use $module_name;";
}

$module_exp =~ s{::}{/}g;
foreach my $key ( grep { m/^$module_exp\./ } keys %INC ) { 
    print "$key => $INC{$key}\n";
}

But I use this more in the form of a korn shell function:

function wherperl
{
     perl -M$1 <<EX_DOC
     my \$module = '$1';
     \$module =~ s/::/\\//g;

     for ( keys %INC ) {
         next unless m/^\$module\./;
         print \$_ . ' => ' . \$INC{\$_} . "\n";
     }
EX_DOC
}
Axeman
  • 29,660
  • 2
  • 47
  • 102
0

I like to use the cpan utility:

% cpan -D YAML
YAML
-------------------------------------------------------------------------
    YAML Ain't Markup Language (tm)
    A/AD/ADAMK/YAML-0.70.tar.gz
    /usr/local/perls/perl-5.10.0/lib/site_perl/5.10.0/YAML.pm
    Installed: 0.68
    CPAN:      0.70  Not up to date
    Ingy dot Net (INGY)
    ingy@cpan.org

This can be a little slow since it has to connect to a CPAN mirror to fetch some of the data, but I also have a local CPAN mirror. :)

brian d foy
  • 129,424
  • 31
  • 207
  • 592