检查并报告缺少Perl模块

VSr*_*VSr 1 perl perl-module

有没有办法事先报告Perl文件中使用的丢失模块,而不是作为错误.

我有一些像use Digest::MD5,use File::DosGlob模块在我的Perl程序.每当用户运行脚本时,如果系统中没有安装特定模块,则会出现错误.他们无法理解由...给出的默认错误消息@INC.所以我想清楚告诉他们需要安装这些模块来运行脚本.

Cha*_*hak 5

您可以使用Devel :: Modlist,它将列出您的程序所需的所有模块.

perl -d:Modlist test.pl
Run Code Online (Sandbox Code Playgroud)

还有另一个模块Module :: ScanDeps,它附带了一个实用程序scandeps.pl,您可以在脚本上使用它:

scandeps.pl test.pl
Run Code Online (Sandbox Code Playgroud)

请注意,检查Perl代码的完整性perl -c是危险的,因此请谨慎使用.


sim*_*que 5

你可以通过建立自己的验证一个BEGIN.那些是在编译时运行的,就像use是.请记住,use Foo基本上没有其他内容如下:

BEGIN {
    require Foo;
    Foo->import;
}
Run Code Online (Sandbox Code Playgroud)

以下代码将use使用单个替换所有语句BEGIN并将它们放在一个中eval.这基本上就像一个try/catch机制.

我们需要字符串eval(这里被认为是邪恶的),因为如果参数是一个单词,require只能从带有冒号的包名转换::为路径.但是因为我们有名字,所以它是一个字符串,所以我们需要将它放入一个根据文档.$moduleevalrequire

如果该字符串eval失败,我们die.这是由外部eval块捕获并$@设置.然后我们可以检查它是否包含我们的模块名称,在这种情况下我们天真地认为失败是因为没有安装该模块.这项检查可能会更精细一些.

我们会记录任何故障$fails,如果有的话,我们就会停止.

#!/usr/bin/perl
use strict;
use warnings;

# all our use statements go here
BEGIN {
    my $fails;
    foreach my $module ( qw/Digest::MD5 File::DosGlob ASDF/ ) {
        eval {
            eval "require $module" or die; # because $module is not a bareword
            $module->import;
        };
        if ($@ && $@ =~ /$module/) {
            warn "You need to install the $module module";
            $fails++;
        }
    }
    exit if $fails;
}

# ...
Run Code Online (Sandbox Code Playgroud)

上面我包括ASDF,我没有,所以在运行时它会说

您需要在/home/code/scratch.pl第1335行安装ASDF模块.

您可能希望使该消息更加冗长.如果您的用户无法理解Perl在找不到模块时提供的默认错误消息,那么在其中包含有关如何安装内容的指南可能是明智之举.

请注意,您列出的两个模块都已包含在Perl中一段时间(阅读:自2002年3月起).那你为什么要为这些模块做这个呢?

$ corelist Digest::MD5

Data for 2014-09-14
Digest::MD5 was first released with perl v5.7.3

$ corelist File::DosGlob

Data for 2014-09-14
File::DosGlob was first released with perl 5.00405
Run Code Online (Sandbox Code Playgroud)

更好的方法是将程序作为可安装的发行版发布,并包含Makefile或cpanfile或列出依赖项的类似内容.perlnewmod中有一个关于如何启动新模块的指南.您不希望显然上传到CPAN,但基本内容是相同的.

有了这个,您的用户将自动安装所有依赖项.