Как вы можете заставить Perl остановиться при обращении к значению undef? - PullRequest
15 голосов
/ 17 сентября 2008

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

Ответы [ 6 ]

20 голосов
/ 17 сентября 2008
use warnings FATAL => 'uninitialized';

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

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

15 голосов
/ 17 сентября 2008

Вместо беспорядочной игры с %SIG, предложенной всеми остальными, просто use <a href="http://search.cpan.org/perldoc?Carp::Always" rel="noreferrer">Carp::Always</a> и готово.

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

4 голосов
/ 17 сентября 2008

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

use Carp ();

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

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

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

1 голос
/ 17 сентября 2008

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

$SIG{__WARN__} = sub { die "Undef value: @_" if $_[0] =~ /undefined/ };
1 голос
/ 17 сентября 2008

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

use Carp qw();

[....]

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

[....]
0 голосов
/ 03 мая 2011

Вы должны сделать это вручную. Вышеуказанные «ответы» не работают! Просто проверьте это:

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

...