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

Hello Wise Monks,

Having some trouble pushing into a hash of an array. It seems that it is just overwriting the array and not adding to it. Any ideas what I'm doing wrong?
while (my $row = $sth->fetchrow_hashref) { $$patients{$row->{'pat_id'}} = { first_name => "$row->{'first_name'}", last_name => "$row->{'last_name'}", pid => "$row->{'pat_id'}" }; push(@{$$patients{$row->{'pat_id'}}->{files}}, $row->{'file_name +'}); $x++; }

Replies are listed 'Best First'.
Re: Push into Hash of Array
by Tanktalus (Canon) on Oct 25, 2005 at 18:49 UTC

    Just to expand a bit on what Roy Johnson said. In your first statement inside the while loop, you assign a brand new hash to $$patients{$row->{'pat_id'}} each time through the loop. Thus, what you probably mean to do is to assign only if it hasn't already been set:

    while (my $row = $sth->fetchrow_hashref) { $$patients{$row->{'pat_id'}} ||= { first_name => "$row->{'first_name'}", last_name => "$row->{'last_name'}", pid => "$row->{'pat_id'}" }; push(@{$$patients{$row->{'pat_id'}}->{files}}, $row->{'file_name +'}); $x++; }
    All I did was add two characters: "||". What that says is to do the assignment if and only if the variable is currently false. Which it would be if not yet set. The first time through the loop for the current pat_id, it will get set to a hash ref which should always be true (if it isn't, it's because we ran out of memory, which is a bigger problem than this anyway), which means we won't assign to it a second time. Try doing a Super Search for "orcish" to see other examples of the OR-Cache (pronounced almost like "orcish") style, which is basically what I'm suggesting here.

      That was the answer. Thank you very much for expanding on that. I will do some reading on OR-Cache.
Re: Push into Hash of Array
by Roy Johnson (Monsignor) on Oct 25, 2005 at 18:08 UTC
    What values is $row->{pat_id} taking on? If it ever repeats, then $$patients{$row->{pat_id}} will be overwritten by the hashref assignment. If it never repeats, then you never push more than one element onto the ->{files} element.

    Caution: Contents may have been coded under pressure.