Как вы можете заставить Perl остановиться при ссылке на значение undef?

Как вы можете заставить Perl остановиться и дать трассировку стека, когда вы ссылаетесь на значение undef, а не просто на предупреждение? Кажется, что use strict; для этой цели недостаточно.

Ответы

Ответ 1

use warnings FATAL => 'uninitialized';

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

Первая строка делает предупреждение фатальным. Следующие две причины вызывают трассировку стека, когда ваша программа умирает.

Ответ 2

Вместо грязной игры с %SIG, предложенной всеми остальными, просто use Carp::Always и сделайте.

Обратите внимание, что вы можете вводить модули в script без изменений источника, просто запустив его с помощью perl -MCarp::Always; кроме того, вы можете установить переменную среды PERL5OPT в -MCarp::Always, чтобы она была загружена, даже не изменяя вызов script. (См. perldoc perlrun.)

Ответ 3

Включите это:

use Carp ();

Затем включите одну из этих строк в верхней части исходного файла:

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

Строка confess даст трассировку стека, а строка cluck намного более кратка.

Ответ 4

Ссылка на значение undef не будет проблемой сама по себе, но может вызвать предупреждения, если ваш код ожидает, что он будет чем-то иным, чем undef. (особенно если вы пытаетесь использовать эту переменную в качестве ссылки на объект). Вы могли бы поместить что-то в свой код, например:

use Carp qw();

[....]

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

[....]

Ответ 5

Один из способов сделать эти предупреждения фатальными - установить обработчик сигнала для виртуального сигнала WARN:

$SIG{__WARN__} = sub { die "Undef value: @_" if $_[0] =~ /undefined/ };

Ответ 6

Вам нужно сделать это вручную. Вышеупомянутые "ответы" не работают! Просто проверьте это:

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 в качестве недопустимой ссылки. Я подозреваю, что это так по дизайну, так что автовивитация работает без проблем.