estreb has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks. I am a very new to hashes in Perl. In the following code, I am creating a hash of hashes of arrays.
#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my @array1 = ( "hello", "world" ); my @array2 = ( "here" ); my @array3 = ( "there" ); my %inner_hash = ( innerkey1 => \@array1, innerkey2 => \@array2, innerkey3 => \@array3 ); my %hash_of_hash_of_arrays = ( key => \%inner_hash ); print Dumper(\%hash_of_hash_of_arrays); exit(0);
This gives the output:
$VAR1 = { 'key' => { 'innerkey2' => [ 'here' ], 'innerkey3' => [ 'there' ], 'innerkey1' => [ 'hello', 'world' ] } };
Is there any way I can get this same output by defining only one variable? Something like:
my %hash_of_hash_of_arrays = { 'key' => { 'innerkey2' => [ 'here' ], 'innerkey3' => [ 'there' ], 'innerkey1' => [ 'hello', 'world' ] } };
...but that gives an error about "Reference found where even-sized list expected", and the output looks like:
$VAR1 = { 'HASH(0x57e1d78)' => undef };
which obviously is not what I want at all. Please help.

Replies are listed 'Best First'.
Re: Creating a hash of hashes of arrays
by toolic (Bishop) on Dec 15, 2014 at 16:57 UTC
    Use parens to construct a hash, not curlies:
    my %hof = ( 'key' => { 'innerkey2' => [ 'here' ], 'innerkey3' => [ 'there' ], 'innerkey1' => [ 'hello', 'world' ] } );

    The curlies are used to construct a reference to a hash.

Re: Creating a hash of hashes of arrays
by Athanasius (Cardinal) on Dec 15, 2014 at 17:13 UTC

    Hello estreb, and welcome to the Monastery!

    As toolic says, to construct a hash you need to change the braces to parentheses:

    my %hash = ( ... ); ... print Dumper(\%hash);

    Alternatively, keep the braces (which construct an anonymous hash and return a reference to it) and assign the result to a scalar variable (because a reference is always a scalar value, regardless of the type of thing it refers to):

    my $hash_ref = { ... }; ... print Dumper($hash_ref);

    Either will give you the output you were expecting. See perlreftut, then perldsc.

    Hope that helps,

    Update: Fixed typo. Thanks to AnomalousMonk and Anonymous Monk.

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Minor typo: my %hash_ref = { ... }; should be my $hash_ref = { ... };
Re: Creating a hash of hashes of arrays
by AnomalousMonk (Archbishop) on Dec 15, 2014 at 18:36 UTC

    It's worth noting that Data::Dumper (core) and Data::Dump (my favorite) and many other, similar modules are designed to produce text that is compilable code. So compiling and running the exact OPed Data::Dumper output (with strict disabled!):

    $VAR1 = { 'key' => { 'innerkey2' => [ 'here' ], 'innerkey3' => [ 'there' ], 'innerkey1' => [ 'hello', 'world' ] } }; print Dumper $VAR1;
    will produce output that is an exact image (replica?) of the structure defined (and that is, in turn, compilable). If you like using strict (a wise choice IMHO), just pre-define the variable with our or, usually better because lexical, my. If you don't like the name, call it something else.
    use warnings; use strict; use Data::Dump qw(dd); my $something_else = { ..., }; dd $something_else;

    Update: For some reason, I can't get either  [mod://Data::Dump] or  [cpan://Data::Dump] to link to the module, but I can see it on CPAN. You'll just have to fend for yourselves.     Later: [mod://Data::Dump] works now. And there was great rejoicing...

Re: Creating a hash of hashes of arrays
by estreb (Novice) on Dec 15, 2014 at 19:14 UTC
    Thanks, all. I have what I need.