Wie erhalten Sie Perl, um zu stoppen und eine Stack-Trace zu geben, wenn Sie einen undef-Wert referenzieren, statt nur zu warnen? Es scheint, dass use strict;
für diesen Zweck nicht ausreicht.Wie kann Perl dazu gebracht werden, beim Referenzieren eines Undef-Wertes zu stoppen?
Antwort
use warnings FATAL => 'uninitialized';
use Carp();
$SIG{__DIE__} = \&Carp::confess;
Die erste Zeile macht die Warnung tödlich. Die nächsten zwei verursachen einen Stack-Trace, wenn Ihr Programm stirbt.
Fügen Sie diese:
use Carp();
Dann sind ein dieser Zeilen am Anfang der Quelldatei:
local $SIG{__WARN__} = \&Carp::confess;
local $SIG{__WARN__} = \&Carp::cluck;
Die confess
Linie wird ein Stack-Trace geben, und die cluck
Linie ist viel knapper.
Das Verweisen auf einen Undef-Wert ist an sich kein Problem, kann jedoch zu Warnungen führen, wenn der Code eine andere als undef erwartet. (besonders wenn Sie versuchen, diese Variable als Objektreferenz zu verwenden). Sie könnten etwas in Ihrem Code setzen wie:
use Carp qw();
[....]
Carp::confess '$variableName is undef' unless defined $variableName;
[....]
Eine Möglichkeit, diese Warnungen fatal zu machen, ist ein Signal-Handler für die virtual-Signal WARN zu installieren:
$SIG{__WARN__} = sub { die "Undef value: @_" if $_[0] =~ /undefined/ };
Statt dem chaotisch fummeln mit %SIG
von allen anderen vorgeschlagen, nur use Carp::Always
und getan werden.
Beachten Sie, dass Sie Module ohne Quellenänderungen in ein Skript einfügen können, indem Sie einfach perl -MCarp::Always
; Außerdem können Sie die Umgebungsvariable PERL5OPT
auf -MCarp::Always
setzen, damit sie geladen wird, ohne den Aufruf des Skripts zu ändern. (Siehe perldoc perlrun
.)
Sie müssen dies manuell tun. Die obigen "Antworten" funktionieren nicht! Testen Sie das einfach:
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";
}
Sie werden sehen, dass Dereferenzierung keine Fehlermeldungen oder Warnungen verursacht. Ich kenne keine Möglichkeit, Perl zu veranlassen, die Verwendung von undef als eine ungültige Referenz automatisch zu erkennen. Ich vermute, das ist so von Design, so dass Autovivification nahtlos funktioniert.
ein leerer Hash erzeugt 0. Dies scheint ein Sonderfall zu sein. – marinara
Als Alternative zu den letzten beiden Zeilen 'carp :: Always' verwenden. –