在 Perl 中抑制无法定位模块警告

Posted

技术标签:

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

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

local $SIG__DIE__= 

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

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

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

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

【问题讨论】:

警告和错误是不同的野兽。 【参考方案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;
  ...
;

【讨论】:

以上是关于在 Perl 中抑制无法定位模块警告的主要内容,如果未能解决你的问题,请参考以下文章

可以在 Visual Studio 2010 中抑制“无法找到或打开 PDB 文件”警告吗?

抑制 django 天真的日期时间警告

Java中@SuppressWarnings注解可以使用的参数列表

SonarQube:如何抑制 Kotlin 代码中的警告

关闭文件时无法抑制剪贴板警告消息

代码生成器生成文件的代码分析 - 如何抑制警告?