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

Hello monks,
I have a question, concerning something i dont have any prior knowledge with, and since i am at home, not at my dorm, no access to my books :(. Here is my question, i am making a hash, in this hash has 5 keys, ill show you below:
%rec = (state => $part1[0], char => $part1[1], stack_char => $part1[2], new_state => $part2[0], new_stack_char => $part2[1]); push (@db, %rec);
this is in a loop, which defines every line in a file. Each line has a state, a char, a stack_char,.. you get the idea, and then this hash is pushed into an array. this is how i am trying to call it, but with no luck, using -w i get the following error:

" Odd number of elements in hash list at p2.pl line 68, <> chunk 8 "

Here is the code:
foreach $hash(@db){ %temphash = $hash; foreach $key( keys %temphash){ print "KEY: $key \n"; print "VALUE: $temphash{$key} \n"; print "________________________\n"; } #end foreach $key }#end foreach $hash
i assume this isnt really the way to define the hash per value in the array, but.. how can i do this??

Thank you very much in advance

2001-03-11 Edit by Corion : Moved to SOPW (who approved this for discussion ?)

Replies are listed 'Best First'.
Re: Hash Array Help
by danger (Priest) on Mar 11, 2001 at 11:27 UTC

    You can't just push a hash onto an array and then expect to extract it back out, you'll need to push a reference to the hash onto the array (and you'll definitely want to make sure %rec is a lexical hash inside your read loop by declaring with my()):

    my %rec = (state => $part1[0], char => $part1[1], stack_char => $part1[2], new_state => $part2[0], new_stack_char => $part2[1], ); push(@db, \%rec);

    Now, when accessing these, you'll need to dereference them:

    foreach my $hash (@db){ foreach my $key( keys %$hash){ print "KEY: $key \n"; print "VALUE: $hash->{$key} \n"; print "________________________\n"; } #end foreach $key }#end foreach $hash

    For further info on references and nested structures, check these perldocs: perlreftut, perlref, perllol, and perldsc.

    update: Hmm, perlreftut doesn't seem to be included in the perlmonks perldocs, but if you have 5.00503 (I think that's when it got included) or later you can read it on your machine.

      Hey guys,
      Thanks for the fast reply. I am still getting a weird output:
      HASH(0x140031c58) HASH(0x140031e28) HASH(0x140031e98) HASH(0x140031f08 +) HASH(0x\ 140031f78) HASH(0x140031fe8) KEY: state VALUE: 0 ________________________ KEY: new_state VALUE: 0 ________________________ KEY: stack_char VALUE: ________________________ KEY: new_stack_char VALUE: a ________________________ KEY: char VALUE: a

      Any ideas?

      thanks again in advance.
        Now that you are using hash references in your array (I assume), you must de-reference them when you use them. If your foreach loop variable is $hash, you must access the hash itself via %$hash

        buckaduck

        Which weird output? Are you talking about the HASH references? I don't see why the code you pasted would print that. Is there another print you added that you haven't told us about?
Re: Hash Array Help
by archon (Monk) on Mar 11, 2001 at 11:29 UTC
    First of all, when you push a hash onto an array like that, you are creating an array of the hash contents so that each key and each value are one element of the array. Your %temphash is being assigned the value of the first key, hence the odd number message. See:
    %foo = ( a => 1, b => 2, c => 3, ); push @bar, %foo; print $bar[0], "\n";
    What you need to do is push a hash reference, i.e. push @bar, \%foo onto the array and then use that value:
    for my $foo (@bar) { print keys (%$foo), "\n"; }