Reputation: 1608
There don't seem to be a lot of examples of people using arrays containing hashes. I want to check the array I am constructing in a sub but I'm having some issues accessing the structure. Perhaps I am not imagining the construct the way it exists. This is an example of some code:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my (%data, %data2, @holding);
%data = (
'monday' => "This stuff!",
'tuesday' => "That stuff!!",
'wed' => "Some other stuff!!!"
);
push @holding, %data;
%data2 = (
'monday' => "Yet more stuff... :-P ",
'tuesday' => "Some totally different stuff!",
'wed' => "What stuff is this?"
);
push @holding, %data2;
foreach my $rows(@holding){
foreach my $stuff (keys %{$holding[$rows]} ){
print "$holding[$rows]{$stuff}\n";
}
}
The error message I get:
Argument "wed" isn't numeric in array element at /home/kingram/bin/test line 27.
Can't use string ("wed") as a HASH ref while "strict refs" in use at /home/kingram/bin/test line 27.
My work with arrays in perl is not extensive so I'm sure I'm missing something basic.
When I use Dumper I am expecting VAR1 and VAR2 expressing two distinct rows but I get
$ ~/bin/test
$VAR1 = [
'wed',
'Some other stuff!!!',
'monday',
'This stuff!',
'tuesday',
'That stuff!!',
'wed',
'What stuff is this?',
'monday',
'Yet more stuff... :-P ',
'tuesday',
'Some totally different stuff!'
];
Upvotes: 1
Views: 5972
Reputation: 69314
Even when you get the data structure right, this code is still not going to work:
foreach my $rows(@holding){
foreach my $stuff (keys %{$holding[$rows]} ){
print "$holding[$rows]{$stuff}\n";
}
}
When you use foreach my $rows (@holding)
to iterate over your array, each time round the loop $rows
will contain an element from the array, not the index of an element. So you don't need to look it up with $holding[$rows]
. You code should look like this:
foreach my $rows (@holding){
foreach my $stuff (keys %{$rows} ){
# $rows will contain a hash *reference*.
# Therefore use -> to access values.
print "$rows->{$stuff}\n";
}
}
Upvotes: 2
Reputation: 54381
You need to work with references. If you push a hash into an array, it's just a flat list. You're using the right dereference operators in your loop, but you're missing a backslash \
when pushing.
push @holding, \%data;
The backslash \
gives you a reference to %data
, which is a scalar value. That will be pushed into your array.
See perlreftut for an explanation.
If you look at @holding
after your two push
operations, it's obvious what happens.
use Data::Printer;
p @holding;
__END__
[
[0] "monday",
[1] "This stuff!",
[2] "tuesday",
[3] "That stuff!!",
[4] "wed",
[5] "Some other stuff!!!",
[6] "wed",
[7] "What stuff is this?",
[8] "monday",
[9] "Yet more stuff... :-P ",
[10] "tuesday",
[11] "Some totally different stuff!"
]
Upvotes: 6