2009-08-12 3 views
5

Ich habe ein YAML Dokument wie folgt aus:Wie kann ich einen YAML-Baum mit Perls YAML :: Tiny laufen?

--- 
version: 1 
rootdirectory: 
    - subdirectory: 
    - file1 
    - file2 
    - subdirectory2 

, die ich in eine YAML bin Laden :: Tiny Objekt wie folgt:

$configuration = YAML::Tiny->read($configuration_file) 

ich den Aufruf des Skripts sehen mit dem Perl-Debugger, was ich am Ende mit einer Reihe von verschachtelten Hashes und Arrays, die die Struktur der YAML Quelle reflektieren:

0 YAML::Tiny=ARRAY(0x84e3ba4) 
    0 HASH(0x80627dc) 
     'rootdirectory' => ARRAY(0x84e3d3c) 
     0 HASH(0x84352b0) 
      'subdirectory' => ARRAY(0x84e3df0) 
       0 'file1' 
       1 'file2' 
     1 'subdirectory2' 
     'version' => 1 

Also, ich kann Dinge wie die folgenden, ohne pr tun oblem:

print $configuration->[0]->{version} 

und die erwartete Antwort von '1' erhalten. Ebenso kann ich auch:

print $configuration->[0]->{rootdirectory}->[0]->{subdirectory}->[0] 

und die erwartete Antwort von 'Datei1' erhalten.

Mein Problem kommt von all dem a-priori-Wissen Ich muss meinen Dateinamen im obigen Beispiel ableiten. Da ich versuche, den Benutzern meines Skripts zu erlauben, eine beliebige Verzeichnisstruktur in der YAML-Konfiguration zu beschreiben, ist das nicht gut genug. Ich muss in der Lage sein, den Baum von "rootdirectory" zu "laufen".

So hätte ich gedacht, ich so etwas getan haben könnte:

print keys($configuration->[0]) 

die ich habe erwartet hätte zurück ‚rootdirectory, Version‘ ... und so weiter, über die Arrays iterieren und Hashes, bis ich den Baum gegangen bin.

Wenn ich das obige Beispiel laufen versuchen, erhalte ich:

Type of arg 1 to keys must be hash (not array element) 

An dieser Stelle ich stecken bin. Wie ich es verstehe, ist $ configuration -> [0], obwohl es ein Element eines Arrays ist, ein Element, das einen Hash enthält, von dem ich glaube, dass ich in der Lage sein sollte, die Schlüsselfunktion dagegen aufzurufen.

Was fehlt mir hier?

Antwort

5

Versuchen

print "$_\n" for keys %{ $configuration->[0] }; 

Sie haben das Array-Element "$configuration->[0]" in einen Hash-ref zu zwingen, mit "%{...}"

So über sie iterieren:

for my $key (keys %{ $configuration->[0] }){ 
    my $value = $configuration->[0]{$key}; 

    print "$key => $value\n"; 
} 
+0

Ausgezeichnet, danke! Wie ich das verstehe, brauche ich im Grunde einige "syntaktische Zucker" in Form von% {$ configuration -> [0]} Perl zu glauben, dass $ Konfiguration -> [0] ist eigentlich ein Hash und kein Array-Element das enthält zufällig einen Hash. Ist das ein fairer Kommentar? –

+0

Ja –

+0

Das Schlüsselwort 'keys()' ist definiert als 'Schlüssel (\%) {...}', was Sie zwingt, einen Hash zu verwenden, aber nicht automatisch für Sie die Dereferenzierung. –

3

YAML::Tiny schafft ein ziemlich komplexe Datenstruktur:

eine Referenz auf ein Array voller Referenzen voller Verweise auf Hashes voller Verweise auf Arrays Hashes ....

wenn $a eine Referenz auf ein Array ist, Sie das gesamte Array als @ zugreifen $ a und die Elemente wie $$a[0], $$a[1], ... oder alternativ als $a->[0], $a->[1]

wenn $b ein referenc auf einen Hash ist, Sie Zugriff auf die gesamte Hash als %$b und die Elemente wie $ $b{'somekey'}, $$b{'somekey'}, .... oder alternativ als $b->{'somekey'}, $b->{'somekey'}

wenn $configuration a Referenz auf ein Array voller Verweise auf Hashes Sie Zugriff auf das gesamte Array als @$configuration, das erste Element als $configuration->[0]. Sie könnten kopieren nur, dass eine andere variable

$firstconfig = $configuration->[0] 

und dann den ganzen Hash zugreifen, als

%$firstconfig 

aber wenn man es in ein tun wollen gehen Sie eher schwierig schreiben

%{ $configuration->[0] } 

Ich denke, das ist einer der Dinge, die für Perl 6 entfernt wurde.

+0

Einige davon wurden * geändert *, aber einige davon sind noch in Perl6 vorhanden. –

+0

YAML :: Tiny baut die serialisierte Datenstruktur einfach neu auf. Die Quelle der Komplexität ist das YAML-Dokument, das analysiert wird. –

+0

Das hat mir sooooo sehr geholfen. Ich habe perlreftut und perldsc gelesen und bin für immer mit Hash-und Array-Referenzen und keine echten Daten in Sicht stecken geblieben. Ich verstehe immer noch nicht ganz, aber wenigstens kann ich mich von der Antwort zur Erleuchtung hinarbeiten. – djeikyb

Verwandte Themen