Ken Ingram Ken Ingram - 2 months ago 15
Perl Question

Perl: How to access Array of Hashes passed to a Subroutine

Have a perl script reading from an xml, parsing the data into hashes in one sub, outputting an array of hashes and then from main calling a second sub to process the array of hashes.

Data::Dumper shows that everything is being passed properly.

Having a terrible time figuring out why I can't now access the hashes.

use strict;
use warnings;
use Data::Dumper;

my (@sortedData, $value1, $value2);
use subs qw(processData outputData);

@sortedData = processData;
outputData($value1, $value2, \@sortedData);

sub processData{
# Example code
# # Does some processing of xml that results in a hash.
# # That series of hashes is pushed onto an array
my ($item, @results);

# foreach $item ( @{ $rss->{items}){
# my %data = (
# 'first' => $item->{'value'},
# 'second' => $item->{'value'},
# 'third' => $item->{'value'}
# );

# push @results, \%data;
# }
# Essentially the hash is :

@results = (
{'data1'=>810,'data2'=>153,'data3'=>215},
{'data1'=>160,'data2'=>220,'data3'=>604},
{'data1'=>940,'data2'=>103,'data3'=>115},
{'data1'=>100,'data2'=>319,'data3',525},
{'data1'=>500,'data2'=>803,'data3'=>650}
);
return @results;
}

sub outputData{
my ($input1, $input2, @localData) = @_;
print Dumper @localData;

print "\@localData: " . @localData . "\n";
foreach my $i (@localData){
# foreach my $j ($i){
# print $i . "\n" . $j . "\n";
# }
print "\$i: " . $i . "\n";
}
}


The output:

$VAR1 = [
{
'data3' => 215,
'data2' => 153,
'data1' => 810
},
{
'data3' => 604,
'data2' => 220,
'data1' => 160
},
{
'data2' => 103,
'data3' => 115,
'data1' => 940
},
{
'data1' => 100,
'data3' => 525,
'data2' => 319
},
{
'data1' => 500,
'data3' => 650,
'data2' => 803
}
];
@localData: 1
$i: ARRAY(0x80071b30)


I don't understand why the value of @localData is 1 or why the reference for an element of @localData is ARRAY instead of HASH.

I am certainly testing my deeper understanding of PERL arrays for the first time.
I don't understand it as much as I thought.

Answer

You pass a reference to the array to the sub, then assign this single scalar to @localData. Fix:

sub outputData{
    my ($input1, $input2, $localData) = @_;
    print Dumper $localData;

    print "\@localData: " . @$localData . "\n";
    foreach my $i (@$localData){
       ...
    }
}