Как заставить Perl останавливаться при обращении к значению undef?

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


person Neil    schedule 16.09.2008    source источник


Ответы (6)


use warnings FATAL => 'uninitialized';

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

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

person cjm    schedule 16.09.2008
comment
В качестве альтернативы последним двум строкам use Carp::Always. - person Stefan Majewsky; 09.10.2012

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

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

person Aristotle Pagaltzis    schedule 16.09.2008

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

use Carp ();

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

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

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

person Neil    schedule 16.09.2008

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

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

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

use Carp qw();

[....]

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

[....]
person mopoke    schedule 16.09.2008

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

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

person user736584    schedule 03.05.2011
comment
пустой хэш дает 0. Похоже, это особый случай. - person marinara; 18.09.2012