W jaki sposób uzyskać Perl zatrzymać i podać ślad stosu, gdy odwołujesz się do wartości undef, a nie tylko ostrzeżenie? Wydaje się, że use strict;
nie jest wystarczający do tego celu.W jaki sposób można uzyskać Perl zatrzymać przy odwoływanie się do wartości undef?
Odpowiedz
use warnings FATAL => 'uninitialized';
use Carp();
$SIG{__DIE__} = \&Carp::confess;
Pierwsza linia sprawia, że ostrzeżenie jest śmiertelne. Następne dwa powodują śledzenie stosu, gdy twój program umiera.
Dołącz następująco:
use Carp();
Wtedy to jeden tych linii na początku pliku źródłowego:
local $SIG{__WARN__} = \&Carp::confess;
local $SIG{__WARN__} = \&Carp::cluck;
Linia confess
da ślad stosu i linię cluck
jest o wiele bardziej zwięzły.
Odwołanie się do wartości niezdefiniowanej nie stanowiłoby problemu samo w sobie, ale może powodować ostrzeżenia, jeśli kod oczekuje, że będzie to coś innego niż undef. (szczególnie, jeśli próbujesz użyć tej zmiennej jako odniesienia do obiektu). Można umieścić coś w kodzie, takich jak:
use Carp qw();
[....]
Carp::confess '$variableName is undef' unless defined $variableName;
[....]
jeden sposób, aby te ostrzeżenia śmiertelne jest zainstalowanie obsługi sygnału dla WARN wirtualnego sygnału:
$SIG{__WARN__} = sub { die "Undef value: @_" if $_[0] =~ /undefined/ };
Zamiast niechlujne błahy z %SIG
zaproponowane przez wszystkich, po prostu use Carp::Always
i gotowe.
Należy zauważyć, że można wprowadzić moduły do skryptu bez modyfikacji źródła, uruchamiając je za pomocą perl -MCarp::Always
; ponadto można ustawić zmienną środowiskową PERL5OPT
na -MCarp::Always
, aby była ładowana bez zmieniania nawet wywołania skryptu. (Patrz perldoc perlrun
.)
Musisz to zrobić ręcznie. Powyższe "odpowiedzi" nie działają! Po prostu przetestuj to:
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";
}
Zobaczysz, że dereferencja nie spowodowała żadnych komunikatów o błędach ani ostrzeżeń. Nie wiem, w jaki sposób spowodować, by Perl automatycznie wykrył użycie undef jako nieważnego odniesienia. Podejrzewam, że jest to zgodne z projektem, dzięki czemu autovivification działa bezproblemowo.
pusta mieszana powoduje 0. To wydaje się być przypadkiem specjalnym. – marinara
Jako alternatywę dla dwóch ostatnich linii używaj 'Carp :: Always'. –