可以“使用严格”警告而不是错误
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】:warnings
和 strict
编译指示是互补的,而不是重叠的。 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 中生成警告而不是错误