2009-08-12 15 views
5

Mam dokument YAML takiego:Jak mogę przejść drzewo YAML za pomocą YAML :: Tiny Perla?

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

że wczytuję w YAML :: Tiny obiekt tak:

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

widzę z wywoływania skryptu Perl z debuggera, że ​​co i skończy się to zestaw zagnieżdżonych skrótów i tablic, które odzwierciedlają strukturę źródła YAML:

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 

więc mogę robić takie rzeczy jak co następuje bez pr Oblem:

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

i otrzymasz oczekiwaną odpowiedź "1". Podobnie, mogę również:

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

i otrzymać oczekiwaną odpowiedź "file1".

Mój problem wynika z całej wiedzy a priori potrzebnej do wyprowadzenia nazwy pliku w powyższym przykładzie. Ponieważ próbuję pozwolić użytkownikom mojego skryptu opisywać dowolną strukturę katalogów w konfiguracji YAML, nie jest to wystarczająco dobre. Muszę być w stanie "chodzić" po drzewie z "rootdirectory".

Tak, chciałbym sobie wyobrazić mogłem zrobić coś takiego:

print keys($configuration->[0]) 

który spodziewałem się, że wrócił „rootdirectory, wersja” ... i tak dalej, iteracja ciągu tablic i do czasu, gdy przeszedłem przez drzewo.

Gdy próbuję uruchomić powyższy przykład, uzyskać:

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

W tym momencie jestem zakleszczony. Jak rozumiem, $ configuration -> [0], będąc elementem tablicy, jest elementem zawierającym skrót, który, jak sądzę, powinien być w stanie wywołać funkcję klawiszy przeciw.

Czego mi tu brakuje?

Odpowiedz

5

Spróbuj

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

Trzeba zmusić element tablicy "$configuration->[0]" w odnośniku hash z "%{...}"

Więc iteracyjne nad nimi:

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

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

Doskonale, dziękuję! Jak rozumiem to ja po prostu potrzebuję trochę „cukier syntaktyczny” w formie% {$ konfiguracji -> [0]}, aby wymusić Perl do uwierzenia, że ​​konfiguracja $ -> [0] jest rzeczywiście hash, a nie element tablicy tak się składa, że ​​zawiera hasz. Czy rzetelnego komentarza? –

+0

Tak –

+0

Klucze słów kluczowych '()' 'jest zdefiniowany jak klucze (\%) {...}' która zmusza do korzystania hash, ale nie auto-dereference dla Ciebie. –

3

YAML::Tiny tworzy raczej złożona struktura danych:

odniesienie do tablicy pełen odniesień do skrótów pełną odniesień do tablic pełną odniesień do skrótów ....

gdy $a jest odwołaniem do tablicy, dostęp całą tablicę jako @ $ a i elementy jako $$a[0], $$a[1], ... lub alternatywnie jako $a->[0], $a->[1]

gdy $b jest referenc do mieszania, dostęp cały hash jako %$b oraz elementy jak $ $b{'somekey'}, $$b{'somekey'}, .... lub alternatywnie jako $b->{'somekey'}, $b->{'somekey'}

gdy $configuration jest odniesienie do tablicy pełen odniesień do mieszań uzyskać dostęp do całego szeregu jako @$configuration, pierwszego elementu jako $configuration->[0]. można po prostu skopiować to do innej zmiennej

$firstconfig = $configuration->[0] 

a następnie dostęp do całego hash jako

%$firstconfig 

ale jeśli chcesz to zrobić za jednym razem trzeba napisać raczej trudne

%{ $configuration->[0] } 

Myślę, że jest to jedna z rzeczy, które zostały usunięte dla Perla 6.

+0

Niektóre która * * zmieniło, ale niektóre z nich nadal istnieje w Perl6. –

+0

YAML :: Tiny właśnie odbudowuje zserializowaną strukturę danych. Źródłem złożoności jest analizowany dokument YAML. –

+0

To bardzo mi pomogło. Czytałem perlreftut i perldsc i utknąłem na zawsze z hasłami i odwołaniami do tablic i żadnych prawdziwych danych w zasięgu wzroku. Nadal nie rozumiem całkowicie, ale przynajmniej mogę wypracować swoją drogę do oświecenia z odpowiedzi. – djeikyb