3.7 Simplifying Nested Element References with Arrows

Look at the curly-brace dereferencing again. As in the earlier example, the array reference for Gilligan's provision list is ${$all_with_names[2]}[1]. Now, what if you want to know Gilligan's first provision? You need to dereference this item one more level, so it's Yet Another Layer of Braces: ${${$all_with_names[2]}[1]}[0]. That's a really noisy piece of syntax. Can you shorten that? Yes!

Everywhere you write ${DUMMY}[$y], you can write DUMMY->[$y] instead. In other words, you can dereference an array reference, picking out a particular element of that array by simply following the expression defining the array reference with an arrow and a square-bracketed subscript.

For this example, this means you can pick out the array reference for Gilligan with a simple $all_with_names[2]->[1], and Gilligan's first provision with $all_with_names[2]->[1]->[0]. Wow, that's definitely easier on the eyes.

If that wasn't already simple enough, there's one more rule: if the arrow ends up between "subscripty kinds of things," like square brackets, you can also drop the arrow. $all_with_names[2]->[1]->[0] becomes $all_with_names[2][1][0]. Now it's looking even easier on the eye.

The arrow has to be between subscripty things. Why wouldn't it be between? Well, imagine a reference to the array @all_with_names:

my $root = \@all_with_names;

Now how do you get to Gilligan's first item?

$root -> [2] -> [1] -> [0]

More simply, using the "drop arrow" rule, you can use:

$root -> [2][1][0]

You cannot drop the first arrow, however, because that would mean an array @root's third element, an entirely unrelated data structure. Let's compare this to the full curly-brace form again:


It looks much better with the arrow. Note, however, that no shortcut gets the entire array from an array reference. If you want all of Gilligan's provisions, you say:


Reading this from the inside out, you can think of it like this:

  1. Take $root.

  2. Dereference it as an array reference, taking the third element of that array (index number 2).

  3. Dereference that as an array reference, taking the second element of that array (index number 1).

  4. Dereference that as an array reference, taking the entire array.

The last step doesn't have a shortcut arrow form. Oh well.[4]

[4] It's not that it hasn't been discussed repeatedly by the Perl developers; it's just that nobody has come up with a nice backward-compatible syntax with universal appeal.