Search code examples
perlreferencecopyperl-data-structures

Populating a perl array of hashes with copies of a single hash


I have searched and searched and I can't get any of the code I've found to work. I'm sorry if this is repeating old ground, but I've now spent 2 days trying to get these 10 lines to work and I am at my wits' end with no hair left :-(

I am running Perl 5.8.8.

I want to populate an array of hashes in Perl such that it contains multiple copies of a single hash variable I am updating. My code is here:

use strict;
use warnings;

my @array;

my %tempHash = (state => "apple", symbol => "54", memberId => "12345");
push(@array, \%tempHash);

%tempHash = (state => "tiger", symbol => "22", memberId => "12345");
push(@array, \%tempHash);

%tempHash = (state => "table", symbol => "37", memberId => "12345");
push(@array, \%tempHash);

printf("%p %p %p\n", $array[0], $array[1], $array[2]);

foreach my $entry (@array){
    printf("state: %s\n", $entry->{state});
    printf("memberId: %s\n", $entry->{memberId});
    printf("symbol: %s\n\n", $entry->{symbol});
}

This produces the following output:

1868954 18688d0 18688c4
state: table
memberId: 12345
symbol: 37

state: table
memberId: 12345
symbol: 37

state: table
memberId: 12345
symbol: 37

So it looks to me like the scalar values in the array are different. Yet the values in the hashes these scalars point to are all the same.

Thanks in advance for your help.


Solution

  • 1) The code you posted doesn't work under use strict;, did you mean %tempHash and %hash are really the same variable?

    2) If you use %s instead of %p, you'll get 3 identical HASH(0x1234abcd) strings, which means the contents of the array are indeed references to the same hash.

    3) I would suggest creating a new anonymous hash each time:

    #!/usr/bin/perl -w
    use strict;
    use Data::Dumper;
    
    my @array;
    my %tempHash = (state => "apple", symbol => "54",memberId => "12345");
    push(@array, { %tempHash });
    
    %tempHash = (state => "tiger", symbol => "22", memberId => "12345");
    push(@array, { %tempHash });
    
    %tempHash = (state => "table", symbol => "37", memberId => "12345");
    push(@array, { %tempHash });
    
    print Dumper( \@array );