views:

395

answers:

4

In Perl 5.10, how do I create and access a hash with scalar keys whose values are arrays?

#Doing this does not work properly.
%someHash= ("0xfff" => ('Blue', 'Red', 'Yellow'));
@arr = @fileContents{"0xfff"};
print @arr;

When I print the array, the only thing that prints is "ARRAY('randmemAddr')". When I do a foreach loop on @arr, only the first element is printed. I have then concluded that I have not stored the array properly in the hash.

+12  A: 

My original answer posted working code, but didn't really explain the problem with yours. This is expanded a bit to correct that. Your example had two problems. First, you had a problem when making the reference. You need to use [ ] instead of the standard parentheses in order to create a reference (to an anonymous array). Second, when you tried to get at the reference, you left off one set of brackets. You want to put the reference itself inside @{ } in order to get at the whole array. (Also, and this may be a typo: you have no $ before filecontents.)

The code here is essentially from perldoc perldsc. I highly recommend it. Also very useful if you're new to references in Perl is perldoc perlreftut. Both tutorials discuss how to make and get at references in a variety of situations. Finally, you can find a good cheat sheet for references in a post on PerlMonks.

#!/usr/bin/env perl
use strict;
use warnings;


my %HoA = (
    flinstones      => [ qw/fred barney/ ],
    jetsons         => [ qw/george jane elroy/ ],
);

for my $family (keys %HoA) {
    print "Members of the \u$family:\n";
    print "\t @{ $HoA{$family} }\n";
}
Telemachus
+1 for posting perldoc references. Note that `perldoc` should be installed and accessible via the command line. The web site is for convenience.
Sinan Ünür
Yup, that's why I always write `perldoc` in code font. But now that I think of it, maybe that isn't an obvious connection to everyone. (That is, if you don't work often in a terminal, or you haven't every used `perldoc` from a terminal, the font may not jump out at you.)
Telemachus
+4  A: 

You need to be more explicit about storing a reference to an array and then dereferencing it.

Try this:

#Doing this doeswork properly.
%someHash= ("0xfff" => ['Blue', 'Red', 'Yellow']);
@arr = @{$fileContents{"0xfff"}};
print @arr;

notice the parens turned to brackets and the cast when using it.

Ry4an
+2  A: 

Hash or array elements are always scalars (except in certain internal uses, not directly possible from Perl), so you can store a reference to an array but not an array.

ysth
+3  A: 

I find it much easier to use Data::Dumper module. Odds are very high that it comes with your perl distribution. It allows you to quickly see what your data structure is.

In your case it would be:

use Data::Dumper;
my %someHash= ("0xfff" => ('Blue', 'Red', 'Yellow'));
print Dumper \%someHash;

This will output:

$VAR1 = {
    'Red' => 'Yellow',
    '0xfff' => 'Blue'
};

of course, to fix it you need to store your array as reference:

use Data::Dumper;
my %someHash= ("0xfff" => [qw(Blue Red Yellow)]);
print Dumper \%someHash;

Which will produce:

$VAR1 = {
            '0xfff' => [
                           'Blue',
                           'Red',
                           'Yellow'
                       ]
        };

Bottom line is Data::Dumper is your best friend

zakovyrya
Data::Dumper is indeed a core module (see "perldoc perlmodlib"), it is therefore included within every up to date distribution of Perl.
fB