检查并报告缺少 Perl 模块

Check and report Perl module missing

有什么方法可以预先报告 Perl 文件中使用的缺失模块,而不是作为错误获取。

我的 Perl 程序中有类似 use Digest::MD5use File::DosGlob 的模块。每当用户 运行 脚本时,如果他们的系统中没有安装特定模块,他们就会收到错误消息。他们无法理解 @INC 给出的默认错误消息。所以我想明确告诉他们,这些模块需要安装到运行脚本中。

您的问题并不清楚 "beforehand" 的含义。要检查 Perl 程序的语法是否正确以及直接包含的模块是否可解析,请使用

perl -c <perl-program.pl>

这会检查您的文件的语法并确保您的代码 used 中的任何模块都存在。但是,它不会传递检查整个依赖树,只会检查 perl-program.pl.

中提到的那些

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

perl -d:Modlist test.pl

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

scandeps.pl test.pl

注意sanity checking your Perl code using perl -c is dangerous,慎用

您可以使用 a BEGIN block. Those are run at compile time, just like use 构建自己的验证。请记住,use Foo 本质上就是这样:

BEGIN {
    require Foo;
    Foo->import;
}

以下代码将用单个 BEGIN 替换所有 use 语句,并将它们置于 eval. That's essentially like a try/catch 机制中。

我们需要字符串 eval(这在这里被认为是邪恶的)因为 require 仅在参数为 [=34= 时才将带有冒号 :: 的包名称转换为路径].

如果那个字符串 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;
}

# ...

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

You need to install the ASDF module at /home/code/scratch.pl line 1335.

您可能希望该消息更详细一些。如果您的用户无法理解 Perl 在找不到模块时给出的默认错误消息,那么明智的做法是在此处包含有关如何安装内容的指南。

请注意,您列出的两个模块都包含在 a while 的 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

更好的方法是将您的程序作为可安装的发行版发布,并包含一个 Makefile 或 cpanfile or something similar that lists dependencies. There is a guide in perlnewmod 以说明如何启动新模块。您显然不想上传到 CPAN,但基本原理是一样的。

这样,您的用户将自动安装所有依赖项。