15

当您引用 undef 值时,如何让 Perl 停止并给出堆栈跟踪,而不仅仅是警告?似乎这use strict;还不够。

4

6 回答 6

20
use warnings FATAL => 'uninitialized';

use Carp ();
$SIG{__DIE__} = \&Carp::confess;

第一行使警告致命。当您的程序终止时,接下来的两个会导致堆栈跟踪。

于 2008-09-16T22:32:25.853 回答
15

%SIG而不是其他人提出的乱七八糟的摆弄,只是和完成。use Carp::Always

请注意,您可以将模块注入脚本而无需修改源代码,只需使用perl -MCarp::Always;运行它即可。此外,您可以将PERL5OPT环境变量设置-MCarp::Always为在不更改脚本调用的情况下加载它。(见perldoc perlrun。)

于 2008-09-16T23:11:35.137 回答
4

包括这个:

use Carp ();

然后在源文件的顶部包含以下行之一:

local $SIG{__WARN__} = \&Carp::confess;
local $SIG{__WARN__} = \&Carp::cluck;

confess行将给出堆栈跟踪,并且该cluck行更加简洁。

于 2008-09-16T22:32:04.047 回答
1

引用 undef 值本身不是问题,但如果您的代码期望它不是 undef 值,它可能会导致警告。(特别是如果您尝试将该变量用作对象引用)。您可以在代码中添加一些内容,例如:

use Carp qw();

[....]

Carp::confess '$variableName is undef' unless defined $variableName;

[....]
于 2008-09-16T22:32:31.893 回答
1

使这些警告致命的一种方法是为WARN虚拟信号安装信号处理程序:

$SIG{__WARN__} = sub { die "Undef value: @_" if $_[0] =~ /undefined/ };
于 2008-09-16T22:33:12.937 回答
0

您必须手动执行此操作。上面的“答案”不起作用!只需测试一下:

use strict;
use warnings FATAL => 'uninitialized';
use Carp ();
$SIG{__DIE__} = \&Carp::confess;

my $x = undef; # it would be enough to say my $x;
if (!$x->{test}) {
print "no warnings, no errors\n";
}

您将看到取消引用不会导致任何错误消息或警告。我知道没有办法让 Perl 自动检测使用 undef 作为无效引用。我怀疑这是设计使然,因此自动生存可以无缝地工作。

于 2011-05-03T17:10:31.193 回答