Perl 5.20 introduces “Key/Value Slices”

Perl v5.20 adds the “Key/Value Slice”, which extracts multiple keys and their corresponding values from a container (hash or array). It uses the %, which is new, legal syntax for a variable name with subscripts after it:


use v5.20;  # you don't need this for the new syntax

my %smaller_hash = %big_hash{ @keys };
my %index_hash   = %big_array[ @indices ];

As with the @ sigil, you know variable type you’re dealing with by the indexing syntax after it. The % does not signify a hash; it denotes that you are getting the index (key) with the value.

Looking at that example, you might mistakenly think that these slices return hashes. They don’t. They return lists which have an index then a value. That’s pairwise like the list representation of a hash, but it can also repeat keys (which hashes can’t do):

use v5.20;  # you don't need this for the new syntax

my %big_hash     = qw( cat Buster dog Addy bird Poppy );

my @array = %big_hash{ qw(cat cat) };

say "@array";

The resulting list duplicates that entries for cat:

cat Buster cat Buster

This new type of slice returns a list, which is just data (i.e. not a variable). That means you can’t use the hash or array operators on the result, which would be a neat trick. You can’t take a reference to the entire result, because that’s the same as taking a reference to a list to get a list of references. The result is not an lvalue, so you can’t assign to it or modify it directly.

Previous to v5.20, you can do the same thing with a map:

my @array = map { $_ => $big_hash{$_} } @keys;

That’s not that bad, making this new feature less than compelling. Use it if you need v5.20 for something else, but don’t make this feature the one that forces people to upgrade.

Further Reading

7 thoughts on “Perl 5.20 introduces “Key/Value Slices””

  1. Do you have any update on the smart operators- given(switch) and smart matching. I have so much production code using these features (hundreds of programs and modules) that I feel that I am now trapped at 5.14.

    My other question is: Do you know when a new release of Effective Perl Programming and The Perl Cookbook are scheduled to release? Sometimes it is easier to buy a book and get a summary of all the new stuff.

  2. There’s no update on the smart match or given. Those are like they were before. In general, you can read the perldelta documentation for each release to see how things changed.

    As far as I know, neither of those books have forthcoming updates.

  3. I am delighted that as usual they do not bother to make these new syntax changes only work under use 5.whateverversion, like was promised.

  4. Do you know if it’s possible to rename the keys on the fly.

    Let’s say I have a big hash with lots of keys that don’t makes sense to a human, and I want to extract/rename those keys so they get meaningful.

  5. There’s not a built-in way to rename keys on the fly, but you could put a map in the middle to change every odd element of the list:

    use v5.20;
    
    my %original = qw(
    	foo     Buster
    	baz     Addy
    	bar     Nigel
    	quux    Poppy
    	);
    
    my %rename = qw(
    	foo  cat
    	baz  dog
    	bar  lizard
    	quux bird
    	);
    
    my %new = map {
    	state $n = 0;
    	$n++ % 2 ? $_ : $rename{$_}
    	} %original{ qw(foo baz) };
    
  6. You aren’t declaring a variable when you get a key-value slice, but like you aren’t declaring a variable when you have a single element access to an array or hash or you have a hash slice. Don’t confuse the sigil with the variable type! This is something we make very clear in Learning Perl, so if you learn it correctly it shouldn’t be confusing.

Comments are closed.