Ich habe Perl-Code ähnlich dem folgenden:
%Vor% Zu keinem Zeitpunkt wird $res
vor dem Iterieren der Abfrageergebnisse gesetzt, der Code läuft jedoch einwandfrei.
Wenn ich print-Anweisungen vor jeden Wert schreibe, bekomme ich in beiden Fällen Leerzeichen, aber wenn die print-Anweisungen nach dem Inkrement kommen, bekomme ich einen Wert von & gt; = 1, abhängig davon, wie viele IPv6-Ressourcen die Organisation hat.
Meine Frage ist, nehme ich an, dass ein nicht initialisierter Hash-Schlüssel in Perl automatisch den Wert Null hat?
Tut mir leid, wenn es als Anfängerfrage erscheint, aber ich kenne ein solches Konstrukt einfach nicht
d.h. $hashref->{foo}->{bar}++
wo ein Wert explizit noch $hashref->{foo}->{bar}
zugewiesen werden muss. Vielen Dank im Voraus!
Der Wert ist nicht automatisch Null. Der Wert ist zunächst undefiniert. Wenn Sie es jedoch wie eine Zahl behandeln (z. B. ++
darauf anwenden), behandelt Perl es wie Null. Wenn Sie sie wie eine Zeichenfolge behandeln (z. B. .
darauf anwenden), behandelt Perl sie wie eine leere Zeichenfolge.
Von perldoc perlsyn
, unter 'Deklarationen':
Die einzigen Dinge, die Sie deklarieren müssen Perl sind Reportformate und Subroutinen (und manchmal nicht einmal Unterroutinen). Eine Variable enthält die undefinierter Wert ("undef") bis es ist wurde ein definierter Wert zugewiesen, der ist alles andere als "undef". Wann Als Nummer wird "undef" behandelt als 0; wenn es als eine Schnur verwendet wird, ist es behandelt als die leere Zeichenfolge, ""; und wenn es als Referenz verwendet wird, ist dies nicht der Fall zugeordnet wird, wird es wie behandelt Fehler.
Um Telemachs Beitrag zu erläutern, sind die nicht initialisierten Werte undefiniert. Die tiefen Teile der Struktur sind autovivifiziert . Dies ist eine praktische Funktion, bei der Datenstrukturen automatisch für Sie erstellt werden. Autovivification ist großartig, wenn Sie es wollen, aber es kann ein Schmerz sein, wenn Sie es verhindern wollen. Es gibt viele Tutorials, Artikel und Posts rund um das Internet zum Verständnis der Autovivi zierung.
Bei einem undefinierten $ref
und $ref->{ipv6}{pa}{'foo'}++
wird $ref
den folgenden Wert zugewiesen:
Dann wird der Undef inkrementiert, da Undef zu 0 wird, erhalten wir 0 ++, was 1 ist.
Für ein Endergebnis von: ref->{ipv6}{pa}{'foo'} == 1
.
Wenn Sie Warnungen aktiviert haben (Sie tun use warnings;
, nicht wahr?), erhalten Sie eine Warnung "nicht initialisierter Wert", wenn Sie mit diesen undefinierten Werten arbeiten. Wenn es das gewünschte Verhalten ist, den vereinheitlichten Wert zu erhöhen, können Sie die gewünschte Gruppe von Warnungen für einen begrenzten Teil Ihres Codes deaktivieren:
Sie finden die Warning-Hierarchie in perllexwarn .
Es ist im Grunde undefiniert, aber behandelt, als ob es Null war, wenn Sie es erhöhen.
Der Ausdruck im Perl-Sprachgebrauch ist "autovivifiziert".
Wahrscheinlich möchten Sie das Keyword exists verwenden:
%Vor% Es gibt keine nicht initialisierte Hash Taste . Die Sache, die nicht initialisiert werden kann, ist der Wert für einen bestimmten Schlüssel. Ein Hash-Wert ist nur ein Skalarwert; Es ist nicht anders als eine Variable wie $foo
.
In Ihrem Beispiel interagieren ein paar verschiedene Perl-Funktionen.
Anfangs $res
ist nicht definiert (d. h. es hat den Wert undef
). Wenn Sie einen nicht initialisierten Wert als Hashreferenz verwenden (wie in $res->{ipv6}...
), "autoviviert" Perl es als eins. Das heißt, Perl erstellt einen anonymen Hash und ersetzt den Wert von undef
durch einen Verweis auf den neuen Hash. Dieser Vorgang wird jedes Mal wiederholt, wenn Sie den resultierenden Wert als Referenz verwenden.
Schließlich autovivifierst du deinen Weg zu $res->{ipv6}{pa}{$row->[2]}
, was undefiniert ist. Denken Sie daran, dass dies nur ein Skalarwert wie $foo
ist. Das Verhalten ist dasselbe wie das Sprechen von
Perl macht besondere Dinge, wenn Sie undefinierte Werte verwenden. Wenn Sie sie als Zahl verwenden, konvertiert Perl sie in 0. Wenn Sie sie als Zeichenfolge verwenden, konvertiert Perl sie in '' (die leere Zeichenfolge). In den meisten Fällen erhalten Sie eine Warnung "Verwendung von nicht initialisierten Werten ...", wenn Warnungen aktiviert sind (was Sie tun sollten). Der Autoinkrement -Operator ( ++
) ist jedoch ein Sonderfall . Aus praktischen Gründen konvertiert es den Wert von undef
nach 0
, bevor er inkrementiert wird.
Tags und Links perl hash default-value