20

I wanted to be able to do this in Perl (the code below is Python lol)

try:
  import Module
except:
  print "You need module Module to run this program."

Does anyone have any idea how to?

Aaron Bertrand
  • 272,866
  • 37
  • 466
  • 490
  • 2
    Related: [How can I check if I have a Perl module before using it?](http://stackoverflow.com/questions/251694) – Brad Mace Dec 04 '12 at 15:43

6 Answers6

19

TIMTOWTDI:

eval "use Module; 1" or die "you need Module to run this program".

or

require Module or die "you need Module to run this program";
Module->import;

or

use Module::Load;

eval { load Module; 1 } or die "you need Module to run this program";

You can find Module::Load on CPAN.

Chas. Owens
  • 64,182
  • 22
  • 135
  • 226
  • the use from your last code statement should start with a lowercase u,right? – Geo Jul 07 '09 at 19:03
  • Yeah, I fixed it and added a link Module::Load's CPAN entry – Chas. Owens Jul 07 '09 at 19:04
  • 4
    Require is fatal on errors, so it must be wrapped in an eval. Also, to be identical to 'use' any require/import code must be in a BEGIN block. So: BEGIN { eval {require 'Module' or die "Ugh."; Module->import; 1 } or do{ die "You lack Module" } } – daotoad Jul 07 '09 at 19:29
11

You can use Module::Load::Conditional

use Module::Load::Conditional qw[can_load check_install requires];


my $use_list = {
    CPANPLUS     => 0.05,
    LWP          => 5.60,
    'Test::More' => undef,
};

if(can_load( modules => $use_list )) 
{
   print 'all modules loaded successfully';
} 
else 
{
   print 'failed to load required modules';
}
Pierre-Luc Simard
  • 2,723
  • 19
  • 27
  • beware: this adds a dependency on rpm-based Linux distributions (e.g. RHEL, Fedora) because they ship Module::Load::Conditional in a separate package. Just saying :-). – Michael Mar 19 '13 at 11:50
  • It was included by default in openSUSE 12.3 (also rpm-based) – Jorge V. May 20 '13 at 02:44
2

Something like this, use Net::SMTP if you have the module installed, or a cheesy sendmail callout as a last resort.

my $mailmethod = eval "use Net::SMTP; 1" ? 'perl' : 'sendmail';
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
hpavc
  • 1,336
  • 7
  • 7
2

There are many modules for doing that; see the list of CPAN modules that (can) load other modules. However, it is a bit risky to rely on an external module (what if it is not present?). Well, at least, if you rely on Moose, Class::Load can be used safely as it is Moose's prerequisite:

#!/usr/bin/env perl
use strict;
use utf8;
use warnings qw(all);

use Class::Load qw(try_load_class);

try_load_class('Module')
    or die "You need module Module to run this program.";
creaktive
  • 5,193
  • 2
  • 18
  • 32
0
use strict;
use warnings;
use Module;

If you don't have Module installed, you will get the error "Can't locate Module.pm in @INC (@INC contains: ...)." which is understandable enough.

Is there some particular reason you want/need a more specific message?

Ether
  • 53,118
  • 13
  • 86
  • 159
  • 2
    It's useful to avoid the app/script dying when the module is used for some optional feature. – Lars Haugseth Jul 07 '09 at 19:18
  • 2
    The error message is understandable for us, but not for "normal" users. And it is verbose enough that many users will probably not even try to read it at all. Even if they do, the error message of course doesn't teach them how to install modules. As someone who has sent a few Perl scripts to several people, I can definitely understand why Pedro asks. – mivk Jan 26 '12 at 22:14
0

Here's how I'm going about it:

sub do_optional_thing {
    init_special_support();
    Module::Special::wow();
}

sub init_special_support {
    # check whether module is already loaded
    return if defined $INC{'Module/Special'};

    eval {
        require Module::Special;
        Module::Special->import();
    };

    croak "Special feature not supported: Module::Special not available" if $@;
}
Brad Mace
  • 27,194
  • 17
  • 102
  • 148