4

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

4

5 回答 5

14

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

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

于 2011-03-25T10:42:20.823 回答
4

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

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

警告也可以在词法上禁用(假设您这样做use warnings而不是很大程度上过时的-w标志)。

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

于 2011-03-25T15:19:04.167 回答
4

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

我怀疑您尝试处理大型、较旧的代码库并希望启用限制,但您希望首先了解错误的位置(以及错误的数量)而不会破坏功能。不幸的是,由于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都是无用的。

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

于 2011-03-29T04:13:54.477 回答
3

首选方法:

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

于 2011-03-25T14:17:39.663 回答
1

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

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

于 2011-03-25T19:48:19.657 回答