【问题标题】:Supress Can't Locate module warning in Perl在 Perl 中抑制无法定位模块警告
【发布时间】:2014-03-18 07:36:02
【问题描述】:

我在 perl 后端服务中实现了记录器。我正在尝试打印被local $SIG{__DIE__}=捕获的内容。

local $SIG{__DIE__}= 

捕获以下错误:无法在 @INC 中找到 xyz.pm(@INC 包含 ....)。

每当我通过命令行运行脚本时,我都看不到终端上生成的上述错误消息。仅本地 $SIG{DIE}= 会捕获此消息。

有什么方法可以抑制找不到警告信息?

我试图通过 perl doc(Category Hierarchy) http://perldoc.perl.org/perllexwarn.html,但我不知道,找不到警告属于哪个类别?

【问题讨论】:

  • 警告和错误是不同的野兽。

标签: perl


【解决方案1】:

这是一个错误,而不是警告。你应该修复这个错误,因为你的脚本在你安装所需的模块之前不会运行。

如果您只是不想记录该特定消息,则可以跳过与某些无趣消息的正则表达式匹配的任何内容:

my $uninteresting_re = qr{\ACan't locate \w+(?:/\w+)*[.]pm in \@INC [(]you may need to install};

$SIG{__DIE__} = sub {
    my ($error) = @_;
    print $log $error unless $error =~ $uninteresting;
    # let error propagation continue as usual
};

【讨论】:

    【解决方案2】:

    如果您实际上并不需要失败的模块来运行您的代码,则可以完全防止“无法定位...”错误的生成。在程序的开头(或至少在它尝试加载缺少的模块之前),添加:

    use PerlIO::scalar;
    BEGIN {
      push @INC, sub { open my $fh, "<", \"1"; return $fh };
    }
    

    这会在@INC 的末尾添加一个条目,如果没有找到实际文件,它将返回一个空的虚拟文件,因此每个use(或require)都会总是找到一些东西加载。

    这不是一个好主意。这远,更有可能掩盖真正的问题,而不是解决任何问题。但如果您真的想冒这个风险,可以这样做。

    【讨论】:

    • 当然,总是可以在sub 中检查正在加载的模块,并且只有在已知它是可选模块时才返回虚拟文件。但是,最好找到加载缺失模块的requireuse 语句,并将其包装在eval {...}try {...} 块中。
    【解决方案3】:

    编写$SIG{__DIE__} 处理程序的正确方法始终是从查看$^S 的值开始。这告诉您eval{} 当前是否正在运行。如果是,你应该忽略它。

    因此,任何处理程序都必须始终启动

    $SIG{__DIE__} = sub {
      return if $^S;
      ...
    };
    

    【讨论】:

      猜你喜欢
      • 2023-02-01
      • 1970-01-01
      • 2011-09-07
      • 2020-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-12
      • 2012-05-09
      相关资源
      最近更新 更多