How do I get a hash slice from a hash of hashes?

hash, perl, perl-data-structures, slice

Solution

To get a hash slice from a nested hash, you have to de-reference it in steps. You get the first level that you need:

$h{'a'}

Now, you have to dereference that as a hash. However, since it's not a simple scalar, you have to put it in braces. To get the whole hash, you'd put a `%` in front of the braces:

%{ $h{'a'} }

Now you want a slice, so you replace the `%` with an `@`, since you're getting multiple elements, and you also put your keys at the end as normal:

@{ $h{'a'} }{ @keys }

It might look easier to see the braces separately:

@{         }{       }
   $h{'a'}    @keys

To make this simpler, v5.20 introduced the postfix dereference. Instead of wrapping thing in braces and working from the inside out, you can work from left to right:

$h{a}->@{qw/one two/};

That `@` is the same thing you saw in front of the first brace. You still know it's a hash slice because a brace follows the sigil.

Problem

I have a hash like so: ``` my %h = ( a => { one => 1, two => 2 }, b => { three => 3, four => 4 }, c => { five => 5, six => 6 } ); print join(',', @{$h{a}{qw/one two/}}); ``` The error I get is: Can't use an undefined value as an ARRAY reference at q.pl line 17 which is the line with the print. What I expected is 1,2

Original source