Как заставить Perl останавливаться и выдавать трассировку стека, когда вы ссылаетесь на значение undef, а не просто предупреждать? Кажется, что use strict;
недостаточно для этой цели.
Как заставить Perl останавливаться при обращении к значению undef?
Ответы (6)
use warnings FATAL => 'uninitialized';
use Carp ();
$SIG{__DIE__} = \&Carp::confess;
Первая строка делает предупреждение фатальным. Следующие два вызывают трассировку стека, когда ваша программа умирает.
use Carp::Always
.
- person Stefan Majewsky; 09.10.2012
Вместо беспорядочной возни с %SIG
, предложенной всеми остальными, просто use Carp::Always
и готово.
Обратите внимание, что вы можете внедрять модули в сценарий без изменения исходного кода, просто запустив его с помощью perl -MCarp::Always
; кроме того, вы можете установить для переменной среды PERL5OPT
значение -MCarp::Always
, чтобы она загружалась, даже не изменяя вызов скрипта. (См. perldoc perlrun
.)
Включите это:
use Carp ();
Затем добавьте одну из этих строк в начало исходного файла:
local $SIG{__WARN__} = \&Carp::confess;
local $SIG{__WARN__} = \&Carp::cluck;
Строка confess
даст трассировку стека, а строка cluck
намного короче.
Один из способов сделать эти предупреждения фатальными — установить обработчик виртуального сигнала WARN:
$SIG{__WARN__} = sub { die "Undef value: @_" if $_[0] =~ /undefined/ };
Ссылка на значение undef сама по себе не будет проблемой, но может вызвать предупреждения, если ваш код ожидает, что это будет нечто иное, чем undef. (особенно если вы пытаетесь использовать эту переменную в качестве ссылки на объект). Вы можете поместить что-то в свой код, например:
use Carp qw();
[....]
Carp::confess '$variableName is undef' unless defined $variableName;
[....]
Вам следует сделать это вручную. Приведенные выше «ответы» не работают! Просто проверьте это:
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 как недействительной ссылки. Подозреваю, что так задумано, чтобы автовивификация работала без проблем.