Question

I am trying to build a Hash that has an array as one value; this array will then contain hashes. Unfortunately, I have coded it wrong and it is being interpreted as a psuedo-hash. Please help!

my $xcHash       = {};
my $xcLine;

#populate hash header

$xcHash->{XC_HASH_LINES} = ();

#for each line of data
    $xcLine       = {};

    #populate line hash

    push(@{$xcHash->{XC_HASH_LINES}}, $xcLine);

foreach $xcLine ($xcHash->{XC_HASH_LINES})
    #psuedo-hash error occurs when I try to use $xcLine->{...}
Was it helpful?

Solution

$xcHash->{XC_HASH_LINES} is an arrayref and not an array. So

$xcHash->{XC_HASH_LINES} = ();

should be:

$xcHash->{XC_HASH_LINES} = [];

foreach takes a list. It can be a list containing a single scalar (foreach ($foo)), but that's not what you want here.

foreach $xcLine ($xcHash->{XC_HASH_LINES})

should be:

foreach my $xcLine (@{$xcHash->{XC_HASH_LINES}})

OTHER TIPS

foreach $xcLine ($xcHash->{XC_HASH_LINES})

should be

foreach $xcLine ( @{ $xcHash->{XC_HASH_LINES} } )

See http://perlmonks.org/?node=References+quick+reference for easy to remember rules for how to dereference complex data structures.

Golden Rule #1

use strict;
use warnings;

It might seem like a fight at the beginning, but they will instill good Perl practices and help identify many syntactical errors that might otherwise go unnoticed.


Also, Perl has a neat feature called autovivification. It means that $xcHash and $xcLine need not be pre-defined or constructed as references to arrays or hashes.

The issue faced here is to do with the not uncommon notion that a scalar can hold an array or hash; it doesn't. What it holds is a reference. This means that the $xcHash->{XC_HASH_LINES} is an arrayref, not an array, which is why it needs to be dereferenced as an array using the @{...} notation.

Here's what I would do:

my %xcHash;

for each line of data:

push @{$xcHash{XC_HASH_LINES}},$xcLine;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top