the usual
inconsistent at best
Perl Hash Reference Slices

Working with Perl’s references can sometimes be confusing. This document illustrates several ways to efficiently take a slice of a hash reference.

Here is a hash reference and an array of keys called @order:

my $row = { foo => 'bar',
            baz => 'blech',
            one => 'uno',
            tres => 'three',
            cuatro => 'four or so' };
my @order = qw(one tres cuatro baz foo);

Here is one way to get a list of values in the order of @order:

my @row = @$row{@order};
say "ROW: @row";

Prints:

ROW: uno three four or so blech bar

If you’re coming from Bourne-shell, you can use lots of curly braces:

@{$row}{@order}

You can also assign slices:

my $old = { foo => 1, bar => 2, baz => 3, blech => 4 };
my @fields = qw(foo bar baz);
my %new = ();
@new{@fields} = @{$old}{@fields};

If we want a slice of a hash of hashrefs:

$sum{foo}->{alpha} = 1;
$sum{foo}->{beta}  = 2;
$sum{foo}->{gamma} = 3;
$sum{foo}->{mu}    = 4;

What we need to remember is that the hashref has to be dereferenced into a hash first with curly braces. This is a hashref containing alpha, beta, etc:

$sum{foo}

Dereferenced to a hash looks like this:

%{$sum{$foo}}

And to take a slice, we use the @ sigil to tell Perl we want (context) an array of values, not key/value pairs:

my @all = @{$sum{foo}}{qw(alpha beta gamma mu)};

Last modified on 2012-05-08