tags:

views:

1052

answers:

7

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.

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

Check out the answers to this earlier question: How can I check if I have a Perl module before using it?

John Siracusa
A: 

How about:

die "Some::Module missing!" unless(eval{require Some::Module});
heeen
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
A: 

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

How are you installing your script? If you are using a standard Makefile.PL or Build.PL, listing dependencies is trivial.

ysth
+2  A: 

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";
}
jeremiah
A: 

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)
 [email protected]

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