Return Multiple Values from a Hash in any Order using Slices

Usually when you access a hash you get a single scalar value back, but it's also possible to get an array of values back - a slice of the hash. To do this all you have to do is pass in an array of keys, rather then a single key, and you'll be given back the values associated with those keys in the same order as the array of keys.

my %simple_hash = ( "a" => "aardvark", "c" => "cat", "e" => "elephant" );
# now to get back more than one value -- note the @ sigil
print join(", ", @simple_hash{"a", "c", "e"})  . "\n"; # aardvark, cat, elephant
my @simple_keys = ("c", "a", "e");
print join(", ", @simple_hash{@simple_keys}) . "\n";   # cat, aardvark, elephant
print join(", ", @simple_hash{qw(e a c)}) . "\n";      # elephant, aardvark, cat

Accessing Values in a Particular Order

Accessing the keys of your hash in a particular order save you a lot of heartburn when you're trying to use those values as input into an SQL insert statement where the order of the values needs to match the ordering of the columns of the table you're trying to insert a record into. It's also useful if you want to apply some kind of sort or post-processing to the order in which you want the values to be returned.

my %input = ( "phone" => "555-555-5555", "username" => "John", "password" => "12345" );
my $sth = $dbh->prepare("INSERT INTO TEST_TABLE
                       ( username, password, phone )
$sth->execute(@input{qw(username password phone)});
print join(", ", @input{sort keys %input}); # 1234, 555-555-5555, John

Merging Hashes

Hash slices also make it very easy to merge two hashes, especially if you want the values from duplicate keys from two different hashes to have there values override the values from the other hash.

my %default_values = ( "color" => "blue", "food" => "pizza", "number" => "7" );
my %user_values    = ( "color" => "green", "dessert" => "ice cream" );
@default_values{keys %user_values} = values %user_values;
print join(", ", values %default_values);  # ice cream, pizza, green, 7
                                           # note blue was overwritten

Slices of Hash References

References to variables always makes things more complicated. Here are some ways to handle those references:

my $hash_ref = \%default_values;
# normal dereference
print $hash_ref->{color} . "\n"; # green
# another way
print $$hash_ref{color} . "\n";  # green
# slightly different way
print ${hash_ref}{color} . "\n"; # green

So how do you apply this to hash slices?:

# second method
print join(@$hash_ref{qw(color food number)}) . "\n";   # green, pizza, 7
# third method
print join(@{$hash_ref}{qw(color food number)}) . "\n"; # green, pizza, 7

You'll notice I skipped the first method. You can play around with the normal derefence, but you'll end up with an assortment of errors trying to slice a hash dereferenced that way.