tags:

views:

82

answers:

1

It seems to me that some of these should fail, but they all output what they are supposed to:

$, = "\n";
%test = (
    "one" => ["one_0", "one_1"],
    "two" => ["two_0", "two_1"]
);

print @{$test{"one"}}[0],
      @{$test{"one"}}->[0],
      $test{"two"}->[0],
      $test{"one"}[1];

Why is this?

+8  A: 

Your first example is different than the others. It is an array slice -- but in disguise since you are only asking for one item.

@{$test{"one"}}[0];

@{$test{"one"}}[1, 0];  # Another slice example.

Your other examples are alternative ways of de-referencing items within a multi-level data structure. However, the use of an array for de-referencing is deprecated (see perldiag).

@{$test{"one"}}->[0]; # Deprecated. Turn on 'use warnings'.
$test{"two"}->[0];    # Valid.
$test{"one"}[1];      # Valid but easier to type.

Regarding the last example, two subscripts sitting next to each other have an implied -> between them. See, for example, the discussion of the Arrow Rule in perlreftut.

FM
It's worth noting that an array slice in scalar context returns the last element in the slice, much like the comma operator `,`.
daotoad