1

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->{...}
1
  • Including use strict; use warnings; would have revealed the problem for you. Commented Nov 19, 2010 at 17:44

4 Answers 4

3

$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}})
Sign up to request clarification or add additional context in comments.

1 Comment

"forward-declaring" $xcHash->{XC_HASH_LINES} is not necessary at all though, as it will be autovivified on first use.
3
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.

Comments

2

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.

2 Comments

Thanks! I do include strict & warnings in my code; I just omitted it here for brevity.
@David : Then you must've posted the code from memory. The code you've posted would not run under the strict and warnings pragmas.
0

Here's what I would do:

my %xcHash;

for each line of data:

push @{$xcHash{XC_HASH_LINES}},$xcLine;

1 Comment

While this is valid advice, it doesn't address the issue at hand

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.