Perl - eval 不捕获 "use"语句

标签 perl

我想检测用户何时缺少必需的模块并打印一条友好的错误消息,说明他们需要安装什么。

到目前为止,我尝试将其放在脚本的开头:

eval {
    use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ;
};
if ($@) {
    die "Error: IO::Uncompress::Gunzip not installed: $@";
}

但是 Perl 似乎死在“使用”行而不是“死”行上,并且从不打印我的错误消息。

最佳答案

use IO::Uncompress::Gunzip qw( gunzip $GunzipError );

简称
BEGIN {
   require IO::Uncompress::Gunzip;
   import IO::Uncompress::Gunzip qw( gunzip $GunzipError );
}

BEGIN block 在编译后立即进行评估。这意味着您的代码可以:
  • 编译阶段:
  • 编译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 中发生异常,eval在步骤 2.1 中运行不会捕获它!

    解决方案:

    你从等同于的东西开始
    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: $@";
    }
    

    (我希望有一种很好的方法来找出是否安装了模块。即使第一个解决方案也会捕获其他错误,第二个甚至更多。)

    关于Perl - eval 不捕获 "use"语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11020911/

    相关文章:

    linux - 通过 mkdir 创建目录

    MySQL 随机查询生成器输出含义

    perl - 如何在 Perl 中增加带有前导零的值?

    Perl - 模板工具包 - 如何获取模板中的变量列表?

    perl - 模块以 "1;"结尾,perlcritic 提示它没有

    php - 这是 no-www 的架构限制吗? :

    perl - 在 Perl 中处理不同基数的命令行参数

    perl - 我可以使用 `Win32::GUI` 为我的命令提示符 Perl 程序创建系统托盘图标吗?

    windows - 如何使用 Perl 操作本地数据库?

    Perl:转向 Class:Struct - 如何自定义新的(即 ctor)?