2012-08-07 10 views
15

Ich bin an dem folgenden Code suchen demonstriert verschachtelte Hashes:Warum werden einige Hashwerte mit geschweiften Klammern initialisiert und einige mit Klammern?

my %HoH = (
    flintstones => { 
     husband => "fred", 
     pal  => "barney", 
    }, 
    jetsons => { 
     husband => "george", 
     wife  => "jane", 
     "his boy" => "elroy", # Key quotes needed. 
    }, 
    simpsons => { 
     husband => "homer", 
     wife  => "marge", 
     kid  => "bart", 
    }, 
); 

Warum ist es, dass die obere meisten Hash (Startlinie 1) initialisiert Klammern verwendet, während die Unter Hashes initialisiert werden mit geschweiften Klammern ?

Kommen aus einem Python-Hintergrund Ich muss sagen, Perl ist ziemlich seltsam :).

Antwort

21

Von Perl her kommend finde ich Perl auch ziemlich merkwürdig.

Verwenden Sie Klammern, um einen Hash (oder ein Array) zu initialisieren. Ein Hash ist eine Map zwischen einer Menge von Strings und einer Menge von skalaren Werten.

%foo = ("key1", "value1", "key2", "value2", ...); # % means hash 
%foo = (key1 => "value1", key2 => "value2", ...); # same thing 

Zahnspangen werden verwendet einen Hash Referenz zu definieren. Alle Referenzen sind skalare Werte.

$foo = { key1 => "value1", key2 => "value2", ... }; # $ means scalar 

Hashes sind nicht skalare Werte. Da die Werte in einem Hash Skalare sein müssen, ist es daher nicht möglich, einen Hash als Wert eines anderen Hash zu verwenden.

Aber wir können Hash-Referenzen als Werte eines anderen Hash verwenden, da Hash-Referenzen Skalare sind.

$foo = { key1 => "value1", key2 => "value2" }; 
%bar = (key3 => $foo); 
%baz = (key4 => { key5 => "value5", key6 => "value6" }); 

Und deshalb sehen Sie Klammern um eine Liste von Listen mit geschweiften Klammern.

+4

Nur der Vollständigkeit halber geben ... es stimmt zwar, dass 'key3 =>% foo' nicht was macht es scheint,' key3 => \% foo' fügt einen Verweis und es ist eine sehr einfache Art, es zu tun, was man sich wünscht d in dieser Situation. –

2

Zuerst ändern die Parens hier nur den Vorrang. Sie haben nichts mit Listenerstellung, Hash-Erstellung oder Hash-Initialisierung zu tun. Sie können Pars um die Operanden des Hash-Erzeugungsoperators,

{ (a => 1, b => 2) } 

verwenden und Sie können die Pars um den Operanden des Zuweisungsoperators weglassen, wenn Vorrang erlaubt.

sub f { return a => 1, b => 2 } 
my %hash = f(); 

Zweitens, initialisiert man nicht einen Hash mit { }; man erstellt daraus einen Hash. { } entspricht my %hash;, außer dass der Hash anonym ist. Mit anderen Worten,

{ EXPR } 

ist grundsätzlich die gleiche wie

do { my %anon = EXPR; \%anon } 

(aber nicht schafft einen lexikalischen Gültigkeitsbereich).

Anonym Hashes ermöglicht eine

my %HoH = (
    flintstones => { 
     husband => "fred", 
     pal  => "barney", 
    }, 
    jetsons => { 
     husband => "george", 
     wife  => "jane", 
     "his boy" => "elroy", 
    }, 
    simpsons => { 
     husband => "homer", 
     wife  => "marge", 
     kid  => "bart", 
    }, 
); 

statt

my %flintstones = (
    husband => "fred", 
    pal  => "barney", 
); 
my %jetsons = (
    husband => "george", 
    wife  => "jane", 
    "his boy" => "elroy", 
); 
my %simpsons = (
    husband => "homer", 
    wife  => "marge", 
    kid  => "bart", 
); 
my %HoH = (
    flintstones => \%flinstones, 
    jetsons  => \%jetsons, 
    simpsons => \%simpsons, 
); 
6

Der wesentliche Unterschied (....) wird verwendet, um schreiben einen Hash zu erstellen. {....} Verwendet, um einen Hash-Referenz

my %hash = (a => 1 , b => 2) ; 
my $hash_ref = { a => 1 , b => 2 } ; 

In etwas mehr Detail zu schaffen - {....} macht einen anonymen Hash und gibt einen Verweis auf sie zu dem skalaren asigned wich ist $hash_ref

bearbeitet ein bisschen mehr Detail

Verwandte Themen