Based on the answer provided here, I am attempting to validate whether or not a perl module is installed. For this, I have:
# &getYN and &prompt are only included here for completeness
sub getYN {
unless ( $autoyes =~ /[Yy]/ ) {
my ( $prompt, $default ) = @_;
my $defaultValue = $default ? "[$default]" : "";
print "$prompt $defaultValue: ";
chomp( my $input = <STDIN> );
return $input ? $input : $default;
} else {
return "Y";
}
}
sub prompt {
my ( $prompt, $default ) = @_;
my $defaultValue = $default ? "[$default]" : "";
print "$prompt $defaultValue: ";
chomp( my $input = <STDIN> );
return $input ? $input : $default;
}
&chklib("RRDTool::OO");
sub chklib {
my $lib = shift;
eval { require $lib; };
if ($@) {
print "You are missing a required Perl Module: $lib\n";
my $ok = &getYN( "Shall I attempt to install it for you?", "y" );
if ( $ok =~ /[Yy]/ ) {
require CPAN;
CPAN::install($lib);
} else {
print "Installation requires $lib\n";
exit;
}
}
}
This runs as expected, but for some reason, the eval returns that I don't have RRDTool::OO installed, when, in fact, I do.
If I create an empty file and run:
# File foo.pl
use strict;
$| = 1;
use RRDTool::OO;
Then I get no errors.
But when I run the first file with print $@;, it returns:
Can't locate RRDTool::OO in ...
What am I doing wrong?
You have to check the result of the eval, like
if (eval("require xxx;")) {
print "you have it\n";
} else {
print "you don't\n";
}
What is happening is that
$lib = "RRDTool::OO";
eval { require $lib }
is executed with the stringified expression
require "RRDTool::OO"
not the bareword style
require RRDTool::OO
so it is looking for a file called RRDTool::OO
in your @INC
path instead of a file called RRDTool/OO.pm
.
If you want to use require
at run-time with a variable expression, you'll want to either use the stringy form of eval
eval "require $lib"
or process the arg to require
yourself
$lib = "RRDTool::OO";
$lib =~ s{::}{/}g;
eval { require "$lib.pm" }