可以“使用严格”警告而不是错误

Posted

技术标签:

【中文标题】可以“使用严格”警告而不是错误【英文标题】:Can 'use strict' warn instead of error 【发布时间】:2011-07-22 19:43:08 【问题描述】:

当使用use strict 时,perl 会在不安全的结构上产生运行时错误。现在我想知道是否可以让它只打印一个警告而不是导致运行时错误?还是use warnings(或-w)警告同样的问题?

【问题讨论】:

你为什么需要那个?如果你真的需要no strict;,你可以对部分代码禁用严格。 原因是我正在使用一个不允许停止的生产关键代码库。同时,我想同时解决这些问题。在这种情况下,通过发出警告并检查完整日志而不是:* 找到中止的运行 *修复问题 *重新运行 *等待几个小时直到在下一个问题中止等等... 【参考方案1】:

不,不能让use strict 发出警告而不是死亡。它所做的只是在神奇的$^H 变量中设置一些位,这会触发 Perl 解释器内部的各种事情。

不,use warnings 并没有警告与 use strict 杀死你一样的事情。例如,use warnings 会警告您变量只使用了一次(这可能是拼写错误的结果)。

【讨论】:

【参考方案2】:

我将尝试猜测这里的真正动机。如果我猜错了,请随时告诉我。

我怀疑您尝试处理大型、较旧的代码库并希望启用限制,但您希望首先了解错误的位置(以及错误的数量)而不破坏功能。不幸的是,由于use strict 通过修改 perl 解析器和解释器的内部行为来发挥作用,因此不存在“宽松严格”或类似于 html 的任何“过渡”模式。

但是,您可以梳理use strict 的功能,以开始朝着正确的方向前进。首先,请注意实际上有三个独立的部分:

use strict 'refs'; # no symbolic references
use strict 'vars'; # must declare variables
use strict 'subs'; # no barewords

其中只有 'refs' 会产生运行时错误。因此,您可以轻松地将use strict qw(vars subs) 添加到您的每个文件(脚本和模块)中,并使用perl -c 对其进行测试。如果您遇到任何错误消息,请注释掉 use strict,或者至少两个检查中的任何一个失败,并添加关于失败性质的注释并继续。通过这种方式,您可以快速(取决于文件的数量)确定哪些文件存在编译时错误,并稍后再回来解决它们。 (如果你现在比我更有动力,你甚至可以自动化这个过程)。除非你有代码在 BEGIN 块内做可怕的事情,否则这样做应该很安全。

比较棘手的部分是检查use strict 'refs' 生成的运行时错误,不幸的是,确实没有一种简单的方法可以做到这一点,因为错误是由符号引用触发的,而符号引用不能由任何类型的静态确定分析so -c 和/或Perl::Critic 都是没用的。

希望这更接近于解决您的实际问题。

【讨论】:

谢谢,您的猜测完全正确。目前我不能只允许这段代码中出现运行时错误,但我确实想最终朝着使用 strict 的方向前进。使用“perl -c”进行检查已经到位,因此跳过 refs 将是第一步。【参考方案3】:

warningsstrict 编译指示是互补的,而不是重叠的。 strict pragma 同时具有编译时和运行时效果。您无法将限制的严重性从错误降低到警告,但您可以完全禁用它们。例如,如果您正在编写自己的导出例程,则需要启用符号引用才能操作符号表。


    no strict 'refs';
    # symrefs okay within this block

警告也可以在词法上禁用(假设您使用use warnings 而不是大部分已过时的-w 标志)。

严格和警告提供了一个安全网。这就是为什么建议默认使用它们的原因。如果您禁用它们,您应该只禁用必要的部分并将更改限制在尽可能小的范围内。

【讨论】:

【参考方案4】:

首选方法:

use Carp;

sub foo 
  croak "no args" unless @_;


eval foo();
if( $@ )
  print "caught die: $@";

如果您无法将die 更改为croak

sub foo 
  die "no args" unless @_;



  my $prev_die = $SIG__DIE__;
  $SIG__DIE__ = sub  print "caught die: $_[0]"; ;
  eval foo();
  $SIG__DIE__ = $prev_die;

第二种方法会在STDERR上打印出错误。

见:

perldoc -f eval

perldoc perlvar 并搜索 /\$\@//__DIE__/

perldoc Carp

【讨论】:

这应该如何避免由 'use strict' 引起的运行时错误?【参考方案5】:

警告可以是致命的——参见perllexwarn——但严格的错误不能是非致命的。

你为什么要这样做?我怀疑是 XY 问题。

【讨论】:

见主要问题下的评论;基本上我想慢慢迁移到使用严格的。不允许当前代码在出现这些严格错误时立即中止。 @Zitrax,然后慢慢添加use strict;(或者慢慢删除no strict;)。忽略警告没有任何好处。

以上是关于可以“使用严格”警告而不是错误的主要内容,如果未能解决你的问题,请参考以下文章

将特定级别的所有警告视为错误,而不是下一级的警告

得到错误而不是不兼容的指针类型警告

使 complierOptions 在 tsconfig 中生成警告而不是错误

使用 .eslintrc.js 将所有 eslint 错误更改为警告而不是错误

mingw g ++以错误的语言发出警告(德语而不是英语)

VSCode:tslint-language-service 插件将 lint 提示显示为错误而不是警告