That was an excellent explanation of the problem.
I thought that it was worth commenting on the two suggested methods of storing the hash ref in the array, because there is a subtle difference between them.
# Method 1 push @data, {%tmp}; # Method 2 push @data, \%tmp;
Method 1 copies the values in %tmp into a new anonymous hash. The reference to the anonymous hash is stored in @data.
Method 2 stores a reference to the %tmp hash.
Either of these approaches could be desirable or lead to interesting bugs, depending on the situation. Other times, it may make almost no difference. In this case, I'd probably use method 2 to avoid an unnecessary copy operation, but I see no strong argument for either approach in this case--it really comes down to personal preference.
The OP might find perldsc and perlreftut to be interesting reading.
BTW, I made a couple of other changes. I used map to generate the hash. It's a bit more compact than the for loop. Another change is using a while loop to read the file. When you use a for loop, you will read the entire file into memory before processing begins. With a while loop, only one line is loaded at a time. Also, note the test in the while loop. The 'defined' is needed to filter out lines evaluate to false in a boolean context--for example: "0\n". I also added a chomp so that the last field doesn't end in "\n" all the time--that gets annoying.
sub read_dat { my $file = shift; my @data = (); while ( defined (my $line = <DATA>) ) { next unless $line =~ m/\w+/; chomp $line; my @line = split (",", $line); my %tmp = map { $columns[$_] => $line[$_] } 0..$#columns; push @data, \%tmp; } return @data; }
Warning: I haven't tested the above code. It may harbor typos and silly logic errors.
TGI says moo
In reply to Re^2: Array of Hashes population
by TGI
in thread Array of Hashes population
by barakuda
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |