检查并报告缺少 Perl 模块
Check and report Perl module missing
有什么方法可以预先报告 Perl 文件中使用的缺失模块,而不是作为错误获取。
我的 Perl 程序中有类似 use Digest::MD5
、use File::DosGlob
的模块。每当用户 运行 脚本时,如果他们的系统中没有安装特定模块,他们就会收到错误消息。他们无法理解 @INC
给出的默认错误消息。所以我想明确告诉他们,这些模块需要安装到运行脚本中。
您的问题并不清楚 "beforehand" 的含义。要检查 Perl 程序的语法是否正确以及直接包含的模块是否可解析,请使用
perl -c <perl-program.pl>
这会检查您的文件的语法并确保您的代码 use
d 中的任何模块都存在。但是,它不会传递检查整个依赖树,只会检查 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,但基本原理是一样的。
这样,您的用户将自动安装所有依赖项。
有什么方法可以预先报告 Perl 文件中使用的缺失模块,而不是作为错误获取。
我的 Perl 程序中有类似 use Digest::MD5
、use File::DosGlob
的模块。每当用户 运行 脚本时,如果他们的系统中没有安装特定模块,他们就会收到错误消息。他们无法理解 @INC
给出的默认错误消息。所以我想明确告诉他们,这些模块需要安装到运行脚本中。
您的问题并不清楚 "beforehand" 的含义。要检查 Perl 程序的语法是否正确以及直接包含的模块是否可解析,请使用
perl -c <perl-program.pl>
这会检查您的文件的语法并确保您的代码 use
d 中的任何模块都存在。但是,它不会传递检查整个依赖树,只会检查 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,但基本原理是一样的。
这样,您的用户将自动安装所有依赖项。