测试脚本中perl mod的存在

时间:2012-04-04 17:03:17

标签: perl

根据提供的答案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 ...

我做错了什么?

2 个答案:

答案 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" }