melguin has asked for the wisdom of the Perl Monks concerning the following question:

I have an array of hashes (not of my making) called @Array. One way to access each hash is:
foreach (@Array) { code here }
So to print the keys of the hashes it makes sense that this should work:
foreach (@Array) { foreach my $tmp (keys %{$Array[$_]}) { print "$tmp\n" } }
However, that gives me a beautiful "Out of memory!" error. So, after looking in Programming Perl, I found out that this is what ://234940]: did you preview your post? It did not look quite right did it? There are links at the bottom of the page to instructions on how to format posts. It would have should work (and it does):
foreach (@Array) { foreach my $tmp (keys %$_) { print "$tmp\n" } }
Why in the world does "%$_" work and not the other?

thanks.

Edited by mirod 2003-02-13: fixed a typo in the title

Replies are listed 'Best First'.
•Re: why is AofH the way it is?
by merlyn (Sage) on Feb 12, 2003 at 21:30 UTC
    For the same reason that this doesn't work:
    my @x = qw(1 2 4 8 16); foreach (@x) { print $x[$_], "\n"; }
    The value in $_ is not the index of the item being scanned. It is the item itself. So on the third iteration of the loop, you're trying to look at $x[4], and on the fourth iteration, $x[8]!

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

Re: Why is AofH the way it is?
by runrig (Abbot) on Feb 12, 2003 at 21:29 UTC
    Because $_ is the hash reference, not the index to the array, and $Array[$_] stringifies the hash reference (to something like "HASH(0x200243d4)", which perl interprets as a "very big" number, and then tries to auto allocate that many elements for your array, and runs out of memory.
      Almost. Perl doesn't stringify the reference--a reference in numeric context is the address, taken as an integer. (Which is why you can compare two references with ==) End result is you have an enourmous array index, which is bad.
Re: Why is AofH the way it is?
by bart (Canon) on Feb 13, 2003 at 09:30 UTC
    Your first code should have looked like this:
    foreach (0 .. $#Array) { foreach my $tmp (keys %{$Array[$_]}) { print "$tmp\n" } }
    The outer loop now uses the array index, not an alias to your array element, as a loop variable. That is what your inner loop expects to see, anyway.