[Update: This feature became stable in Perl v5.24]

Perl v5.20 offers an experimental form of dereferencing. Instead of the complicated way I’ll explain in the moment, the new postfix turns a reference into it’s contents. Since this is a new feature, you need to pull it in with the feature pragma (although this feature in undocumented in the pragma docs) (Item 2. Enable new Perl features when you need them. and turn off the experimental warnings:

use v5.20; use feature qw(postderef); no warnings qw(experimental::postderef);

To turn an array reference into its elements, after the arrow -> you use @ with a star, * after it:

my @elements = $array_ref->@*;

This also works with the anonymous array constructor, although you would be wrapping that package just to unwrap it. Sometimes consistent syntax is like that:

my @elements = [ qw(cat bird dog) ]->@*;

In prior versions, you have to use the circumfix notation to do the same thing:

my @elements = @$array_ref; my @elements = @{ $array_ref };

The new notation is handy for things such as foreach which needs a list:

foreach my $element ( $array_ref->@* ) { ... }

This feature is more interesting when the reference doesn’t come from a variable and you can’t conveniently use the circumfix notation. Perhaps the reference is the return value of a subroutine:

sub some_sub { state $ref = [ qw(cat dog bird) ]; $ref; } foreach my $element ( some_sub()->@* ) { ... }

This works for all of the reference types, although the subroutine version is a bit weird. I’ll get to the subroutine postfix dereference later.

If you use a subscripty thing after the postfix sigil to get a single element of a slice:

my $first = some_sub()->@[0]; my @slice = some_sub()->@[0,-1];

The single element access is not that interesting because you can already do that without the postfix sigil:

my $first = some_sub()->[0];

Here’s an interesting bit of Perl syntax. What happens when you put two indices in that?

my( $first ) = some_sub()->[0, -1];

Perl doesn’t think that’s a slice so it treats the expression inside the braces in scalar context. The comma in scalar context evaluates the left had side, discards the result, evaluates the right hand side, and returns the result. It’s the same thing as the behavior in the FAQ What is the difference between a list and an array?.

In this code, only $first gets a value, but it’s from the last subscript, while $second gets none:

my( $first, $second ) = some_sub()->[ do { say "Evaluated!"; 0 }, 1 ]; say "First is $first"; say "Second is $second";

Perl evaluates the first “subscript”, but doesn’t use it. It uses the last result in the comma chain, even though the assignment looks like it’s in list context.

Wedge that postfix @ in there and both $first and $second get values:

my( $first, $second ) = some_sub()->@[ do { say "Evaluated!"; 0 }, 1 ]; say "First is $first"; say "Second is $second";

Don’t make the common mistake of associating the @ with an array. Just like the array and hash slices, Perl figures out the type with the the subscripty braces.

A postfix hash slice still has the @ and gives back a list of values:

sub get_hashref { state $ref = { cat => 'Buster', dog => 'Addy', bird => 'Poppy', }; $ref; } my( $first, $second ) = get_hashref()->@{ qw(cat dog) }; say "First is $first"; say "Second is $second";

Curiously, in all of this, the subroutine with the postfix dereference is always called in scalar context despite what you are doing with the result or how you are assigning it. A reference is always a scalar, and that’s a single thing.

Scalar and array interpolation

You can interpolate the postfix dereference notation with scalar and array references if you enable the postderef_qq feature (also undocumented in the pragma docs):

use v5.20; use feature qw(postderef postderef_qq); no warnings qw(experimental::postderef); my $scalarref = \ 'This is the string'; say "Scalar is < $scalarref->$* >"; my $arrayref = [ qw(cat bird dog) ]; say "Array is < $arrayref->@* >";

Notice that without the postderef feature, Perl would try to interpolate the $* (a Perl 4 multi-line feature removed in v5.10).

I’ve only found one useful demonstration of the postfix scalar dereference. Mojo::JSON uses references to the literals 0 and 1 to represent JSON’s true and false . The postfix dereference gets you the boolean value:

use Encode qw(encode); use Mojo::JSON qw(decode_json); use Mojo::Util qw(dumper); my $raw_octets = encode( 'UTF-8', '{"name":"Bender","robot":true}' ); my $hash = decode_json( $raw_octets ); say "$hash->{name} is a robot? ", $hash->{robot}->$* ? 'Yes' : 'No';

To appreciate the ease of the postfix dereference notation, you should understand the circumfix notation which earlier versions use. I cover this in Intermediate Perl, but here’s a short explanation.

Remember the notation for an array variable. There’s a sigil to give some context, an identifier (the name), and possible subscripts:

SIGIL IDENTIFIER SUBSCRIPT

In Perl, you can put whitespace between those parts and it still works, including with the new key/value slice syntax:

@ IDENTIFIER $ IDENTIFIER [ 0 ] @ IDENTIFIER [ @indices ] % IDENTIFIER [ @indices ] % IDENTIFIER $ IDENTIFIER { 'cat' } @ IDENTIFIER { @keys } % IDENTIFIER { @keys }

You can replace IDENTIFIER with a reference. This is the circumfix notation, called that because there’s stuff around the thing you’re dereferencing. The general syntax uses braces around the reference, which, like in the previous section, might be something that produces a reference and not a variable:

@ { REFERENCE } $ { REFERENCE } [ 0 ] @ { REFERENCE } [ @indices ] % { REFERENCE } [ @indices ] % { REFERENCE } $ { REFERENCE } { 'cat' } @ { REFERENCE } { @keys } % { REFERENCE } { @keys }

If the REFERENCE is a simple scalar variable (not a single element access, a subroutine call, or something else), you can omit the braces:

@ $array_ref $ $array_ref [ 0 ] @ $array_ref [ @indices ] % $array_ref [ @indices ] % $hash_ref $ $hash_ref { 'cat' } @ $hash_ref { @keys } % $hash_ref { @keys }

Now, suppose you have an array of arrays of arrays of hashes, just to look at something complicated:

my $array = [ [ [ { animal => 'cat', name => 'Buster' }, ] ... ], ... ];

To get the first element of the array reference, you can dereference with the circumfix notation. This gives you the first array reference under the top level reference, leaving off the braces because the top level is in a simple scalar variable:

$array_ref[0]

To get the first item from that reference, you have to use the braces since that’s a not simple scalar variable:

${ $array_ref[0] }[0]

To get all the elements from that reference, you add more braces:

@{ ${ $array_ref[0] }[0] }

It’s the same with the arrow notation (even implied!) which makes the inside only slightly prettier but still needs the outside braces:

@{ $array_ref->[0]->[0] }

You can leave off the arrows between subscripts:

@{ $array_ref->[0][0] }

It’s no wonder some people think Perl is ugly.

The postfix dereferencing looks nicer because it doesn’t use the braces, but it also keeps everything in order from left to right:

$array_ref->[0][0]->@*

You need that extra arrow at the end; it’s a syntax error otherwise:

$array_ref->[0][0]@* # syntax error!

The postfix dereference for a subroutine is slightly odd because there are different ways that you can call a subroutine, but the postfix dereference uses one of the uncommon ones.

Start with a named subroutine. With just the & and no parentheses, the called subroutine gets the arguments in the current version of @_ :

local @_ = qw(Buster Mimi Ginger); sub some_sub { "@_" } say "With &: ", &some_sub; # With &: Buster Mimi Ginger say "With &(): ", &some_sub(); # With &():

The postfix dereference form has the same behavior. It executes the subroutine reference with the current @_ . Dereferencing the sub reference with ->() is different; it specifies an empty argument list:

use v5.20; use feature qw(postderef); no warnings qw(experimental::postderef); my $sub = sub { "@_" }; local @_ = qw(Buster Mimi Ginger); say $sub->&*; # Buster Mimi Ginger say $sub->(); #

Things to remember