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

I'm not sure what's wrong with the follwing code. I'm
trying to create an array of anonymous hashes but each
element of the array contains the last hash I pushed on.

#!/usr/bin/perl
use strict;

my @list = qw(1 Mike testing 2 Richard testing2 3 David Testing3);
my @records;
my $r = {};

my $c = 1;
LOOP: foreach my $f (@list) {
  if ($c == 1) { $r->{id}      = $f }
  if ($c == 2) { $r->{name}    = $f }
  if ($c == 3) {
    $r->{subject} = $f;
    print "Pushing Id: $r->{id}\t Name: $r->{name}\t Subject: $r->{subject}\n";
    push(@records, $r);
    $c = 1;
    next LOOP;
  }
  $c++;
}

for (my $i = 0; $i <= 2; $i++) {
  print "ID:   $records[$i]->{id} ";
  print "Name: $records[$i]->{name} ";
  print "Subject: $records[$i]->{subject}\n";
}
}

Replies are listed 'Best First'.
RE: Array of hash
by chromatic (Archbishop) on Mar 24, 2000 at 22:33 UTC
    Here's what I ended up with:
    #!/usr/bin/perl -w use strict; my @list = qw(1 Mike testing 2 Richard testing2 3 David Testing3); my @records; my $r; my $c = 1; foreach my $f (@list) { if ($c == 1) { $r->{id} = $f } if ($c == 2) { $r->{name} = $f } if ($c == 3) { $r->{subject} = $f; print "Pushing Id: $r->{id}\t Name: $r->{name}\t Subject: $r->{sub +ject}\n"; # print "Anonymous hash: $r\n"; push(@records, $r); $c = 1; $r = {}; next; } $c++; } foreach (@records) { print "ID: $_->{id}\t"; print "Name: $_->{name}\t"; print "Subject: $_->{subject}\n"; }
    If you comment out the line where I assign $r to a new anonymous hash and uncomment the line where I print out the value of $r, you'll notice that it refers to the same hash. Since $r and $array[0], $array1, and $array2 are all references to the same hash, when you replace a value with one reference, you're replacing it in the one hash.

    For further proof, move the right curly bracket from beneath the $c++; line to the end of the file. That will loop through @records each time and show you the change in the one hash. Solution? Make a new hash each time through the loop.

    (Damian Conway describes references as "fingers pointing at the moon". You're copying fingers, but not making new moons.)

RE: Array of hash
by mc (Initiate) on Mar 24, 2000 at 21:57 UTC
    Not sure how that extra } got in there on the last line. Sorry.