[PERL] Vaag gedoe met hash references

Pagina: 1
Acties:

  • jeroen|IA
  • Registratie: Juni 1999
  • Laatst online: 26-05-2025
Hoi,

Ik ben een tijdje bezig geweest met het programmeren van een subroutine die m.b.v. recursieve aanroepen een hash van references naar hashes van willekeurige diepte kan uitprinten.

Deze routine pakt als argument een reference naar een hash (efficienter dan de hash zelf te passen) en loopt vervolgens deze hash af tot hij een value tegenkomt die weer een reference is naar een hash, dan roept hij zichzelf opnieuw aan met deze reference als parameter. Redelijk simpel. De routine waar het om gaat is deze:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sub printrecursivehash {

   for my $i (@_)  {
      return false if (ref($i) ne "HASH");
      while ( ($key, $val) =  each %{$i} ) {
         if (ref($val) eq "HASH") {
            print "$key:\n";
            &printrecursivehash( \%{$val} );
         } else {
            print "$val\t$key\n";
         }
      }
      print "\n";
   }
}

Mijn vraag heeft betrekking op de recursieve aanroep van zichzelf met een hashref als parameter in regel 8. Zoals gezegd werkt het nu wel, maar ik snap niet waarom. De (lelijke) syntax \%{$val} betekent volgens mij namelijk: dereference $val zodat je een hash hebt, en pass het adres van die hash als nieuw argument voor de recursieve aanroep. Met andere woorden: pass een nieuwe reference. Mahaar.... dat was $val zelf ook al! Als ik van de aanroep echter het volgende maak:

code:
1
&printrecursivehash( $val );

dan wordt telkens alleen het eerste key, value pair van de subhash geprint. Zelfs als ik er van maak:

code:
1
2
$temphashref = \%{$val};
&printrecursivehash( $temphashref );

dan gebeurt dat ook! Als ik aan het begin van mijn sub een print ref($i) plaats om te kijken wat voor argumenten hij binnen krijgt is het in alle gevallen een HASH. Wat gaat hier nou mis? Iemand?

  • jeroen|IA
  • Registratie: Juni 1999
  • Laatst online: 26-05-2025
Hmm... de oplossing zat em in de scope van de variabelen. Hier nog het goede script, voor de liefhebbers ;)

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sub printrecursivehash {

   for my $i (@_)  {
      return if (ref($i) ne "HASH");
      my($key, $val);
      while ( ($key, $val) = each(%{$i}) ) {
         if (ref($val) eq "HASH") {
            print "$key:\n";
            &printrecursivehash( $val );
         } else {
            print "$val\t$key\n";
         }
      }
      print "\n";
   }
}

[ Voor 16% gewijzigd door jeroen|IA op 16-11-2003 19:00 ]