Cool new Perl feature: postfix dereferencing

Postfix dereferencing is a cool new feature coming in the next major Perl release. Although Perl version 5.20 is not due until the Spring, you can use the postfix dereferencing feature with the Perl developer release now.

Requirements

You’ll need to install a copy of the latest Perl developer release (v5.19.8). You can get this with Perlbrew:

$ perlbrew install perl-5.19.8
$ perlbrew switch perl-5.19.8

Or you can download and build Perl v5.19.8 from cpan.org.

Once 5.19.8 is installed, you’ll need the experimental distribution. Install it via cpan at the command line:

$ cpan experimental

Circumfix dereferencing primer

In Perl we’re used to using the circumfix operation to dereference variables. The circumfix operation involves wrapping our reference in curly braces and prepending the appropriate variable sigil. For example, to dereference an array:

my $array_ref = [1, 2, 3];
push @{$array_ref}, 4;

Here we declare an array reference, then use the circumfix operation (“@{}”) to dereference the array, enabling us to push the scalar onto the array. Stylistically the circumfix operation is ugly. Perl syntax is already awash with sigils and curly braces and we don’t need any more. Circumfix dereferences can also be hard to read in the case of deeply nested references, as the dereferencing sigil is on the left, whilst the chain of dereferencing arrows grow to the right:

my $deep_array_ref = [[[[[1,2,3]]]]];
push @{$deep_array_ref->[0][0][0][0]}, 4;

Enter postfix dereferencing

Postfix dereferencing is a new feature and a drop-in replacement for circumfix dereferencing. Instead of wrapping the reference with a circumfix operation, we append a dereferencing sigil to the end of the reference. Let’s revisit the previous two examples using postfix dereferencing:

use experimental 'postderef';

my $array_ref = [1, 2, 3];
push $array_ref->@*, 4;

my $deep_array_ref = [[[[[1,2,3]]]]];
push $deep_array_ref->[0][0][0][0]->@*, 4;

Here we dereferenced the arrays using the postfix operation (“->@*”). You can even get the array’s last element index:

use experimental 'postderef';

my $array_ref = [1, 2, 3];
my $last_element_index = $array_ref->$#*;

This is cleaner than circumfix as there are no extra curly braces, it’s more intuitive as it follows left-to-right precedence and nested references are easier to read as we don’t have to track back to the beginning of the reference to locate the sigil. We have a winner!

Postfix dereference works anywhere circumfix does

Arrays aren’t the only beneficiary of this new feature. Postfix dereferencing works with scalars, hashes, coderefs and globs too:

use experimental 'postderef';
use feature 'say';

my $scalar   = 'hello world!';
my %hash     = ( hello => 'world!' );
my $code     = sub { say 'hello world!' };

my $sundry_ref = [  \$scalar,
                    \%hash,
                     $code ];

# scalar
say $sundry_ref->[0]->$*;

# hash
for (keys $sundry_ref->[1]->%*) { say "$_ $sundry_ref->[1]{$_}" }

# coderef
$sundry_ref->[2]->&*;

Conclusion

Postfix dereferencing syntax is cleaner and easier to follow than circumfix. If you haven’t seen it already, check out Perl pumpking, Ricardo Signes presenting postfix dereferencing at NYC.pm (the rest of the talk is great too).

For more postfix dereferencing examples, take a look at the Perl source test file and the new perlref.

Enjoyed this article? Help us out and retweet it!

Tags

David Farrell

David is the founder and editor of PerlTricks.com. An organizer of the New York Perl Meetup, he works for ZipRecruiter as a software developer.

Browse their articles