Perl’s dereferencing syntax might be, or even should be, responsible for people’s disgust at the language. In v5.20, Perl added the experimental postfix dereferencing syntax that made this analogous to method chaining. This is one of the most pleasing Perl features I’ve encountered in years.
Now you can leave out the pragmas to enable the experimental feature and turn off its warning. This example defines a subroutine $gimme_a_ref
that returns an array ref that contains a hash ref. In the foreach
I dereference the subroutine to get the array ref, use postfix dereferencing to pull out the first array element, then dereference that value to be a hash that I can use with keys
. That’s a lot going on, but just like I explained it in this paragraph, I write it from left to right in code:
use v5.24; my $gimme_a_ref = sub { state $hash_ref = { cat => 'Buster', dog => 'Addy', }; [ $hash_ref ]; }; foreach my $key ( keys $gimme_a_ref->()->@[0]->%* ) { say "key is $key"; } my %hash = reverse $gimme_a_ref->()->@[0]->%*; say Dumper( \%hash ); use Data::Dumper;
If you don’t remove the feature
or no warnings
or update the version, v5.24 will not issue the experimental feature warnings, or even warnings that this feature is no longer experimental:
# v5.24 won't warn about any of these use v5.22; use feature qw(postderef); no warnings qw(experimental::postderef);
To review the alternatives to this new feature, see the examples I provided in Use postfix dereferencing.
I believe the @ in “->@[0]” is superfluous. “->@[…]” gets a slice, and a slice of one will act like you want, here, but the traditional “->[0]” would do.
That “->%*” though? That’s the stuff!
As in many examples simple enough to fit in a short blog post, there might be a simpler way to do it. That doesn’t show off the feature, though.
If I understand this feature correctly, two simple examples would be:
my @array = $array_ref->@*;
my %hash = $hash_ref->%*;
Very cool. But…
Isn’t the reference type known when we want to de-reference it???
Why can’t we omit the sigil, like this:
my @array = $array_ref->*;
my %hash = $hash_ref->*;
Why did the language designers chose “@*” and “%*” instead of a simple “*”?
If the type: array @ or hash %, is not specified then when reading the code, one would not know what variable type it is without going elsewhere to look it up.
It’s the same reason any variables have sigil attached, to give a visual indication of their type. It’s the Perl way.
traditional “->[0,1]” would not do
To my mind would be much better if list inside [] will mean @[]