使用use strict
perl 时会在不安全的构造上生成运行时错误。现在我想知道是否可以让它只打印一个警告而不是导致运行时错误?还是use warnings
(或-w)警告同样的问题?
5 回答
不,use strict
不能发出警告而不是死亡。它所做的只是在魔法变量中设置一些位$^H
,这会触发 Perl 解释器内部的各种事情。
不,use warnings
不是警告与use strict
杀死你一样的事情。例如,use warnings
将警告您只使用一次的变量(这可能是拼写错误的结果)。
warnings
和pragma 是互补的strict
,而不是重叠的。pragma同时strict
具有编译时和运行时效果。您无法将限制的严重性从错误降低到警告,但您可以完全禁用它们。例如,如果您正在编写自己的导出例程,则需要启用符号引用才能操作符号表。
{
no strict 'refs';
# symrefs okay within this block
}
警告也可以在词法上禁用(假设您这样做use warnings
而不是很大程度上过时的-w
标志)。
严格和警告提供了一个安全网。这就是为什么建议默认使用它们的原因。如果你禁用它们,你应该只禁用必要的东西,并将更改限制在尽可能小的范围内。
我将尝试猜测这里的真正动机。如果我猜错了,请随时告诉我。
我怀疑您尝试处理大型、较旧的代码库并希望启用限制,但您希望首先了解错误的位置(以及错误的数量)而不会破坏功能。不幸的是,由于use strict
通过修改 perl 解析器和解释器的内部行为来发挥作用,因此没有“松散严格”或类似于 html 的任何类型的“过渡”模式。
但是,您可以梳理一下 的功能,use strict
以便开始朝着正确的方向前进。首先,请注意实际上有三个独立的部分:
use strict 'refs'; # no symbolic references
use strict 'vars'; # must declare variables
use strict 'subs'; # no barewords
而那些只有“参考”会产生运行时错误。因此,您可以轻松地添加use strict qw(vars subs)
到每个文件(脚本和模块)并使用perl -c
. 如果您遇到任何错误消息,请注释掉use strict
,或至少两个检查中的任何一个失败,并添加关于失败性质的注释并继续。通过这种方式,您可以快速(取决于文件的数量)确定哪些文件存在编译时错误,并稍后再回来解决它们。(如果你现在比我更有动力,你甚至可以自动化这个过程)。除非你有代码在块内做可怕的事情,否则BEGIN
这应该是很安全的。
更棘手的部分是检查由生成的运行时错误use strict 'refs'
,不幸的是,确实没有一种简单的方法可以做到这一点,因为错误是由符号引用触发的,而符号引用无法通过任何类型的静态分析来确定,所以 -c 和/或Perl::Critic都是无用的。
希望这更接近解决您的实际问题。
首选方法:
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
警告可以是致命的——参见perllexwarn——但严格的错误不能是非致命的。
你为什么要这样做?我怀疑是 XY 问题。