2016-07-29 25 views
1

Dies kann etwas sehr einfaches für Sie sein, aber ich habe es für mehr als eine Stunde versucht.Perl-Pass-Hash-Verweis auf Subroutine von Foreach-Schleife (Array of Hash)

Ok .. Hier ist mein Code,

@collection = [ 
{ 
      'name' => 'Flo', 
      'model' => '23423', 
      'type' => 'Associate', 
      'id' => '1-23928-2392', 
      'age' => '23', 
}, 
{ 
      'name' => 'Flo1', 
      'model' => '23424', 
      'type' => 'Associate2', 
      'id' => '1-23928-23922', 
      'age' => '25', 
}]; 

foreach my $row (@collection) { 
    $build_status = $self->build_config($row); 
} 

sub build_config { 
    my $self = shift; 
    my %collect_rows = @_; 
    #my %collect_rows = shift; 

    print Dumper %collect_rows; exit; 
    exit; 
} 

Wo Reihe $ ist wirklich ein Hash. Aber wenn ich es Drucken .. Es gibt eine Ausgabe wie unten (Ich bin mit Dumper),

$VAR1 = 'HASH(0x20a1d68)'; 
+0

Ich vermute, Sie haben wirklich '@collection = (...)', nicht '@collection = [...]'. Sonst würden Sie etwas wie $ VAR1 = 'ARRAY (0x20a1d68)'; '. – ThisSuitIsBlackNot

+0

ha .. Was ist der Unterschied zwischen ihnen? (...) ist für Hash und [...] ist für Array. Habe ich recht? Weil dies wie @collection = [...] im Code deklariert ist. – Raja

Antwort

5

Sie sind verwirrend Referenzen mit Hashes und Arrays.

Ein Array mit erklärt:

my @array = (1, 2, 3); 

Ein Hash mit deklariert wird:

my %hash = (1 => 2, 3 => 4); 

das, weil ist beide Hashes und Arrays listet einfach sind (Phantasie-Listen, aber ich schweife ab). Sie müssen [] und {} nur dann verwenden, wenn Sie die in der Liste enthaltenen Werte verwenden oder einen Verweis auf eine der beiden Listen erstellen möchten (weiter unten).

Beachten Sie, dass die => ist nur ein besonderes (dh. Fett) Komma, die auf die linke Seite zitiert, so dass, obwohl sie das gleiche tun, %h = (a, 1) brechen würde, %h = ("a", 1) funktioniert gut, und %h = (a => 1) funktioniert auch gut, weil die a wird zitiert.

Ein Array Referenz wird als solche deklariert:

my $aref = [1, 2, 3]; 

... beachten Sie, dass Sie die Array-Referenz in eine skalare setzen müssen. Wenn Sie dies nicht tun und tun es wie folgt aus:

my @array = [1, 2, 3]; 

... wird die Referenz auf das erste Element der @array geschoben, das ist wahrscheinlich nicht das, was Sie wollen.

Eine Hash-Referenz wird wie folgt erklärt:

my $href = {a => 1, b => 2}; 

Das einzige Mal, [] auf einem Array verwendet wird (kein Aref) ist, wenn Sie es verwenden um ein Element zu verwenden: . Ähnlich wie bei Hashes, wenn es sich nicht um eine Referenz handelt, verwenden Sie nur {}, um den Wert eines Schlüssels zu erhalten: $hash{a}.

, jetzt Ihr Problem zu beheben, können Sie die Verweise mit diesen Änderungen weiter verwenden:

use warnings; 
use strict; 

use Data::Dumper; 

# declare an array ref with a list of hrefs 

my $collection = [ 
    { 
     'name' => 'Flo', 
     ... 
    }, 
    { 
     'name' => 'Flo1', 
     ... 
    } 
]; 

# dereference $collection with the "circumfix" operator, @{} 
# ...note that $row will always be an href (see bottom of post) 

foreach my $row (@{ $collection }) { 
    my $build_status = build_config($row); 
    print Dumper $build_status; 
} 

sub build_config { 
    # shift, as we're only accepting a single param... 
    # the $row href 

    my $collect_rows = shift; 
    return $collect_rows; 
} 

... oder es ändern sich nicht-Refs zu verwenden:

my @collection = (
    { 
     'name' => 'Flo', 
     ... 
    }, 
    { 
     'name' => 'Flo1', 
     ... 
    } 
); 

foreach my $row (@collection) { 
    my $build_status = build_config($row); 

    # build_config() accepts a single href ($row) 
    # and in this case, returns an href as well 

    print Dumper $build_status; 
} 

sub build_config { 
    # we've been passed in a single href ($row) 

    my $row = shift; 

    # return an href as a scalar 

    return $row; 
} 

Ich schrieb Ein Tutorial über Perl-Referenzen, die Sie interessieren könnten guide to Perl references. Es gibt auch perlreftut.

Ein letzter Punkt ... die Hashes werden mit {} innerhalb des Arrays deklariert, weil sie in der Tat Hash-Referenzen sind.Bei mehrdimensionalen Daten kann nur die oberste Ebene der Struktur in Perl mehrere Werte enthalten. Alles andere darunter muss ein einzelner Skalarwert sein. Daher können Sie ein Array von Hashes haben, aber technisch und wörtlich ist es ein Array, das Skalare enthält, deren Wert ein Zeiger (Verweis) auf eine andere Struktur ist. Der Zeiger/Verweis ist ein einzelner Wert.

+2

Das ist wunderbar ... Danke! – Raja

+0

herzlich willkommen. Ich hoffe, es hat – stevieb

+0

geholfen, weil es nicht Teil der Frage war, die ich nicht ausführlich erklären werde, werde ich das sagen ... refs sind oft der bevorzugte Weg zu gehen, wenn Daten weitergegeben werden, wie beim Übergeben von Arrays oder Hashes herum, führt es dazu, dass Perl Kopien der Strukturen erstellen muss, anstatt nur einen Zeiger zu senden. Wenn Sie an einem Ref arbeiten, arbeiten Sie an der ursprünglichen Struktur. Ein Fall, in dem Sie die tatsächliche Variable senden möchten, ist, wenn Sie eine Kopie benötigen, damit die ursprüngliche Struktur in der Arbeit, die Sie ausführen müssen, nicht geändert wird. – stevieb