我想检测用户何时缺少必需的模块并打印友好的错误消息,说明他们需要安装的内容。
到目前为止,我尝试将其放在脚本的开头:
eval {
use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
};
if ($@) {
die "Error: IO::Uncompress::Gunzip not installed: $@";
}
但Perl似乎死于"使用"而不是" die"行,永远不会打印我的错误信息。
答案 0 :(得分:10)
use IO::Uncompress::Gunzip qw( gunzip $GunzipError );
是
的缩写BEGIN {
require IO::Uncompress::Gunzip;
import IO::Uncompress::Gunzip qw( gunzip $GunzipError );
}
和BEGIN
块在编译后立即进行评估。这意味着你的代码确实:
eval
语句。
BEGIN
块。
require IO::Uncompress::Gunzip;
import IO::Uncompress::Gunzip qw( gunzip $GunzipError );
BEGIN
阻止。
require IO::Uncompress::Gunzip;
import IO::Uncompress::Gunzip qw( gunzip $GunzipError );
if
声明。eval
声明。 if
声明。如果在步骤1.1.2.1中发生异常,则步骤2.1中的eval
运行将无法捕获它!
解决方案:
你从等同于
的东西开始BEGIN {
require IO::Uncompress::Gunzip;
import IO::Uncompress::Gunzip qw( gunzip $GunzipError );
}
您希望捕获的require
错误,因此只需在eval
周围添加require
:
BEGIN {
eval { require IO::Uncompress::Gunzip }
or die "Error: IO::Uncompress::Gunzip not installed: $@";
import IO::Uncompress::Gunzip qw( gunzip $GunzipError );
}
您还可以使用use
代替eval EXPR
来延迟eval BLOCK
编译(并因此评估):
BEGIN {
eval 'use IO::Uncompress::Gunzip qw( gunzip $GunzipError ); 1'
or die "Error: IO::Uncompress::Gunzip not installed: $@";
}
(我希望有一种很好的方法可以找出是否安装了一个模块。即使第一个解决方案会捕获其他错误,第二个解决方案会更多。)
答案 1 :(得分:5)
这里发生的是模块在编译时是use
d,无论它是否在eval
块内。
这也是naab's suggestion从eval BLOCK
形式更改为eval EXPR
形式的原因;表达式在运行时进行评估。
将use
更改为require
将尝试在运行时加载模块:
eval {
require IO::Uncompress::Gunzip;
IO::Uncompress::Gunzip->import( qw/gunzip $GunzipError/ ) ;
};
if ($@) {
die "Error: IO::Uncompress::Gunzip not installed: $@";
}
<强>输出强>
错误:IO :: Uncompress :: Gunzip未安装:无法在@INC中找到IO / Uncompress / Gunzip.pm(@INC包含:C:/ Perl / site / lib C:/ Perl / lib。)在线2。
答案 2 :(得分:0)
查看Class :: Load的try_load_class(CPAN)
use Class::Load;
die "Error: IO::Uncompress::Gunzip not installed" if
(! try_load_class (IO::Uncompress::Gunzip));
但据我所知,你不能用Class :: Load导入qw(gunzip $ GunzipError)。