【问题标题】:Perl warning printed without 'use warnings' or -w in any files在任何文件中打印的 Perl 警告没有“使用警告”或 -w
【发布时间】:2018-01-13 04:26:26
【问题描述】:

我有很多经常被调用的旧 Perl 代码,我一直在编写一个新模块,突然间,我在 Apache 的 error_log 中收到了很多警告,它们针对当前正在使用的每个模块.例如,

"my" variable $variable masks earlier declaration in same statement at
    /path/to/module.pm line 40 (#1)

Useless use of hash element in void context at
    /path/to/another/module.pm line 212 (#2)

代码库的主要布局是一个巨大的脚本,其中包含模块并将请求定向到为网站创建某些页面所需的模块,然后主脚本处理菜单等静态元素。

我当前的项目与这个主脚本分离并且不使用它但是任何时候我使用 ajax 调用我的代码时,还有一些其他的 ajax 调用将使用主脚本,并且警告似乎只出现在这些请求中但仅当我调用我的项目时。

我已经对每个模块进行了 grep,但没有一个模块在其中使用警告(或 -w),我也尝试在主脚本和我自己的项目中使用 no warnings 'all',但它什么也没做。

在这一点上,我不知道下一步该做什么,所以感谢所有帮助,我只是想禁止警告,代码库很旧而且写得不好,所以要纠正每个导致首先警告是不可行的。

Apache 服务器也在运行 mod_perl,如果这可能会有所不同,我觉得这可能与 CGI 有关,但我似乎找不到任何证据。

【问题讨论】:

    标签: ajax apache perl cgi mod-perl


    【解决方案1】:

    我认为代码是通过运行某些顶级 Perl 脚本来调用的。

    然后在这些脚本中使用__WARN__ 挂钩来停止打印警告

    BEGIN { $SIG{__WARN__} = sub {} };
    

    将此BEGIN 块放在use 语句之前,以便也影响模块。

    由于__WARN__ 不支持'IGNORE',因此空子例程是使警告静音的方法。

    warn%SIG in perlvar。 有关 cmets 和一些示例,请参阅 this postthis post


    要进一步调查和跟踪警告,您可以使用Carp

    BEGIN {
        $SIG{__WARN__} = \&Carp::cluck;  # or Carp::confess; to also die
    }
    

    这将使它打印完整的堆栈跟踪。这可以根据需要进行微调,因为我们可以编写自己的 sub 来调用。或者使用Carp::Always

    this post 一些更激烈的措施(比如覆盖CORE::GLOBAL::warn

    一旦找到抑制警告的更精确级别,如果可能,local $SIG{__WARN__} 就是要走的路。这是在上面链接的帖子中使用的,这里是another example。当然,最好只在需要的地方而不是在任何地方禁止警告。

    更多细节

    请注意,不幸的是,longmess 不再那么标准和得到很好的支持。

    【讨论】:

    • 嗯,当我将它实现到主文件中时,它似乎不起作用,但是当我将它实现到我的项目中时它确实起作用了,将其标记为已解决,我希望能够找到是什么导致它从这里开始。干杯。
    • 太棒了。我正准备放松“在主程序中”的声明,因为我不了解项目的结构。感谢您的署名。
    • @Fashim 更新了,这就是我的意思。我希望它会更好。为了跟踪它,您可以将警告更改为die(请参阅其中一个链接的帖子),然后打印完整的堆栈跟踪。我会在帖子中添加对此的评论。
    • @Fasim 添加了有关如何尝试跟踪警告从何处触发的想法
    • 啊,太棒了,非常感谢,对于模糊的描述感到抱歉,代码真的很糟糕。
    猜你喜欢
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-03
    • 2013-10-23
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多