How to check if I have a Perl module before using it?

I have the following Perl code that relies on Term::ReadKey to get the width of the terminal; This module is missing in my NetBSD assembly, so I want to use the default terminal width to 80 when the module is missing.

I cannot understand how to conditionally use a module, knowing in advance whether it is available. My current implementation simply terminates with a message saying that it cannot find Term::ReadKey if it is missing.

 #/usr/pkg/bin/perl -w # Try loading Term::ReadKey use Term::ReadKey; my ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize(); my @p=(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97); my $plen=$#p+1; printf("num |".("%".int(($wchar-5)/$plen)."d") x $plen."\n",@p); 

I use Perl 5.8.7 on NetBSD and 5.8.8 on CygWin. Can you help me implement this in my script more efficiently?

+42
module perl
Oct 30 '08 at 20:41
source share
6 answers

Here is a boneless solution that does not require another module:

 my $rc = eval { require Term::ReadKey; Term::ReadKey->import(); 1; }; if($rc) { # Term::ReadKey loaded and imported successfully ... } 

Note that all the answers are below (I hope they are lower than this! :-), which use eval { use SomeModule } , are erroneous because use statements are evaluated at compile time no matter where they are in the code. Therefore, if SomeModule not available, the script will die immediately after compilation.

(The eval line of the use statement will also work ( eval 'use SomeModule'; ), but it makes no sense to parse and compile the new code at run time, when the require / import pair does the same, and is checked by the syntax at compile time for loading.)

Finally, note that my use of eval { ... } and $@ is concise here for the purposes of this example. In real code, you should use something like Try :: Tiny, or at least be aware of the problems it is facing .

+81
Oct. 30 '08 at 21:07
source share
— -

Check out the CPAN Module :: Load :: Conditional . He will do what you want.

+10
Oct 30 '08 at 20:53
source share

The classic answer (starting with Perl 4, at least long before "use" appeared) was to "require ()" a module. This is executed when the script is run, not when compiled, and you can check for success or failure and react accordingly.

+6
Oct 30 '08 at 21:23
source share

And if you need a specific module version:

 my $GOT_READKEY; BEGIN { eval { require Term::ReadKey; Term::ReadKey->import(); $GOT_READKEY = 1 if $Term::ReadKey::VERSION >= 2.30; }; } # elsewhere in the code if ($GOT_READKEY) { # ... } 
+4
Nov 04 '08 at 10:35
source share
 if (eval {require Term::ReadKey;1;} ne 1) { # if module can't load } else { Term::ReadKey->import(); } 

or

 if (eval {require Term::ReadKey;1;}) { #module loaded Term::ReadKey->import(); } 

Note: 1; runs only when load correctly require Term::...

+4
May 05 '09 at 6:43 a.m.
source share

I think this does not work when using variables. Please check this link which explains how it can be used with a variable

 $class = 'Foo::Bar'; require $class; # $class is not a bareword #or require "Foo::Bar"; # not a bareword because of the "" 

The require function will look for the file "Foo :: Bar" in the @INC array and will complain that it will not find "Foo :: Bar" there. In this case, you can do:

  eval "require $class"; 
0
Oct 23 '14 at 0:45
source share



All Articles