0

根据此处提供的答案,我正在尝试验证是否安装了 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 ...

我究竟做错了什么?

4

2 回答 2

2

您必须检查评估的结果,例如

if (eval("require xxx;")) {
     print "you have it\n";
} else {
     print "you don't\n";
}
于 2012-04-04T17:19:13.963 回答
2

正在发生的事情是

$lib = "RRDTool::OO";
eval { require $lib }

用字符串化的表达式执行

require "RRDTool::OO"

不是简单的风格

require RRDTool::OO

所以它正在寻找一个RRDTool::OO在你的@INC路径中调用的文件,而不是一个名为RRDTool/OO.pm.

如果您想require在运行时使用变量表达式,您需要使用字符串形式的 eval

eval "require $lib"

require或自己处理 arg

$lib = "RRDTool::OO";
$lib =~ s{::}{/}g;
eval { require "$lib.pm" }
于 2012-04-04T17:22:08.303 回答