Frage

Ich ringe mit einigen Perl, die Hashreferenzen verwendet.

Am Ende stellte sich heraus, dass mein Problem war die Zeile:

$myhash{$key} |= {};

Das heißt, "$ myhash {$ key} einen Verweis auf einen leeren Hash zuweisen, es sei denn, es bereits einen Wert hat".

Dereferenzierung diese und versuchen, es als Hash-Referenz zu verwenden, jedoch ergab Interpreter Fehler über einen String als Hash-Referenz.

Ändern Sie es an:

if( ! exists $myhash{$key}) {
  $myhash{$key} = {};
}

... die Dinge funktionieren.

So habe ich nicht ein Problem . Aber ich bin gespannt, was los war.

Kann mir jemand erklären?

War es hilfreich?

Lösung

Der Grund, warum Sie einen Fehler sind zu sehen, um einen String als Hash-Referenz verwendet, weil Sie den falschen Operator verwenden. |= bedeutet "bitweise-or-assign." Mit anderen Worten:

  $foo |= $bar;

ist die gleiche wie

  $foo = $foo | $bar

Was passiert in Ihrem Beispiel ist, dass Ihre neue anonyme Hashreferenz Zeichenfolge wird immer dann bitweise ODER-Verknüpfung mit dem Wert von $myhash{$key}. Um die Sache weiter zu verwirren, wenn $myhash{$key} zu dem Zeitpunkt nicht definiert ist, ist der Wert die einfache stringification der die Hash-Referenz, die wie HASH(0x80fc284) aussieht. Wenn Sie also eine oberflächliche Prüfung der Struktur zu tun, kann es aussehen wie eine Hash-Referenz, aber es ist nicht. Hier einige nützliche Ausgabe über Data::Dumper:

   perl -MData::Dumper -le '$hash{foo} |= { }; print Dumper \%hash'
   $VAR1 = {
             'foo' => 'HASH(0x80fc284)'
           };

Und hier ist das, was Sie bekommen, wenn Sie den richtigen Operator verwenden:

  perl -MData::Dumper -le '$hash{foo} ||= { }; print Dumper \%hash'
  $VAR1 = {
            'foo' => {}
          };

Andere Tipps

Perl hat Stenografie Zuweisungsoperatoren. Der ||= Operator wird häufig auf Standardwerte für die Variablen aufgrund Perl Merkmal mit logischen Operatoren geben den letzten Wert ausgewertet verwendet. Das Problem ist, dass Sie |= verwendet, die ein bitweise oder anstelle von ||=, welches ein logischer oder.

Wie von Perl 5.10 ist es besser //= stattdessen zu verwenden. // ist die logische definiert-oder Betreiber und nicht scheitern in der Ecke Fall, in dem der aktuelle Wert definiert ist aber falsch.

Ich denke, Ihr Problem "|=" (bitweise oder Zuweisung) anstelle von "||=" wurde mit (zuweisen, wenn false).

Beachten Sie, dass Ihr neuer Code nicht genau entspricht. Der Unterschied besteht darin, dass „$myhash{$key} ||= {}“ ersetzt vorhandene-but-falschen Werte mit einer Hash-Referenz, aber die neuen nicht. In der Praxis ist dies wahrscheinlich nicht relevant.

Versuchen Sie folgendes:

my %myhash;
$myhash{$key} ||= {};

Sie können einen Hash deklarieren -Element in einer my Klausel, soweit ich weiß. Sie erklären den Hash zuerst, dann in das Element hinzuzufügen.

Edit: Ich sehe Sie die my herausgenommen haben. Wie wäre es ||= statt |= versuchen? Ersteres ist idiomatisch für „faul“ Initialisierung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top