根据提供的答案here,我试图验证是否安装了perl模块。 为此,我有:
# &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;
}
}
}
这会按预期运行,但由于某种原因,eval会返回我没有安装RRDTool :: OO的情况,事实上我已经这样做了。
如果我创建一个空文件并运行:
# File foo.pl
use strict;
$| = 1;
use RRDTool::OO;
然后我没有错误。
但是当我使用print $ @;运行第一个文件时,它返回:
Can't locate RRDTool::OO in ...
我做错了什么?
答案 0 :(得分:2)
你必须检查eval的结果,比如
if (eval("require xxx;")) {
print "you have it\n";
} else {
print "you don't\n";
}
答案 1 :(得分:2)
正在发生的事情是
$lib = "RRDTool::OO";
eval { require $lib }
使用字符串化表达式执行
require "RRDTool::OO"
不是裸字风格
require RRDTool::OO
所以它正在RRDTool::OO
路径中寻找名为@INC
的文件,而不是名为RRDTool/OO.pm
的文件。
如果要在运行时使用带有变量表达式的require
,则需要使用eval的字符串形式
eval "require $lib"
或自行处理arg到require
$lib = "RRDTool::OO";
$lib =~ s{::}{/}g;
eval { require "$lib.pm" }