有什么方法可以事先报告Perl文件中使用的缺失模块,而不是将其作为错误报告。检查并报告缺少Perl模块
我在我的Perl程序中有类似use Digest::MD5
,use File::DosGlob
模块。每当用户运行脚本时,如果他们的系统中没有安装特定的模块,他们就会收到错误信息。他们无法理解@INC
给出的默认错误消息。所以我想清楚地告诉他们需要安装这些模块来运行脚本。
有什么方法可以事先报告Perl文件中使用的缺失模块,而不是将其作为错误报告。检查并报告缺少Perl模块
我在我的Perl程序中有类似use Digest::MD5
,use File::DosGlob
模块。每当用户运行脚本时,如果他们的系统中没有安装特定的模块,他们就会收到错误信息。他们无法理解@INC
给出的默认错误消息。所以我想清楚地告诉他们需要安装这些模块来运行脚本。
您可以使用a BEGIN
block构建自己的验证。这些是在编译时运行的,就像use
一样。请记住,use Foo
基本上没有别的,因为这:
BEGIN {
require Foo;
Foo->import;
}
下面的代码将取代所有use
语句与单个BEGIN
并将它们放置一个eval
内。这基本上就像一个try/catch机制。
我们需要串eval
(这被认为是邪恶在这里),因为require
只用冒号::
为路径包名称转换,如果参数为a bareword。但是因为我们的名称是$module
,它是一个字符串,所以我们需要根据require
's docs将它放入eval
。
如果该字符串eval
失败,我们die
。这被外部eval
区块所捕获,并设置了[email protected]
。然后我们可以检查它是否包含我们的模块名称,在这种情况下,我们天真地认为失败是因为该模块未安装。这项检查可能会更详细。
我们跟踪$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 ([email protected] && [email protected] =~ /$module/) {
warn "You need to install the $module module";
$fails++;
}
}
exit if $fails;
}
# ...
上面我包括ASDF
,而我没有,所以在运行时,它会说
您需要在/home/code/scratch.pl线1335安装ASDF模块。
您可能希望使该消息更加冗长。如果您的用户无法理解Perl在找不到模块时提供的默认错误消息,那么可以明智地包含关于如何在此处安装东西的指南。
请注意,您列出的两个模块已包含在Perl中,用于a while(阅读:自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或东西,列出了相关。 perlnewmod中有关于如何启动新模块的指南。你不想显然上传到CPAN,但基本是一样的。
这样,你的用户就可以自动安装所有的依赖关系。
你的问题并不清楚“预先”的含义。要检查Perl程序的语法是正确的,直接计入模块解析,使用
perl -c <perl-program.pl>
这将检查文件的语法,并确保您的代码D任何模块use
存在。但是,它不会过渡检查整个依赖关系树,只有在perl-program.pl
中提到的依赖关系树。
如果你的意思是你的代码使用模块'use'd,那么是的,它是的。它不能做的是检查在运行时使用'require'加载的模块。 – mbethke
如果'test1.pl'在同一个目录下使用'test2.pm',并且'test2.pm'有一个糟糕的'use'语句,它将只被一个expicit'perl -c test2.pm'捕获,而不是' perl -c test1.pl' –
适用于perl 5.24,我非常确定它一直如此。 '$ echo'使用X;“ > x.pl; echo“package X; use Y;” > X.pm; perl -c x.pl'导致'Can not locate Y.pm in @ INC' – mbethke
您可以使用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,所以小心使用。
感谢提及_perlnewmod_。我一直想知道CPAN如何获得人口。 – PerlDuck
除了那个doc @PerlDuck还有很多。有各种工具可以启动新的发行版,还有一些指南。也许这是在CPAN上发布一些东西的好时机。开始建立一个暂停帐户。 :) – simbabque
我真的不熟悉生成文件或cpanfile,开始工作的单个文件谢谢你,但如果我想检查文件夹中的所有perl文件如何可以做 – VSr