mable
mable

Reputation: 71

How can I dereference an array of arrays of arrays?

I'm working on a Perl Dancer2 webapp and stumbled across the situation that I have an array that contains arrays that contain an array in position 2. I pass a reference to that array to a sub and then iterate over the array (that contains arrays).

When I try to get the innermost array inside a foreach() loop with @$$_[2], I get an error:

Not a SCALAR reference

I can easily work around this with:

my $ref = $$_[2];
print "@$ref\n";

but I wonder why the first approach doesn't work.

Have a look at my minimal example:

my @x = (["a", "b", [1, 2], "c"],
         ["x", "y", [8, 9], "z"]);
my $y = \@x;

foreach (@$y) {
#   print "@$$_[2]\n"; #produces error

    my $z = $$_[2];
    print "@$z\n"; #works
}

Any ideas what is going on here?

Upvotes: 1

Views: 113

Answers (2)

choroba
choroba

Reputation: 242323

You need curly braces:

@{$$_[2]}

or, more readable

@{ $_->[2] }

The original @$$_[2] is interpreted as

@{ $$_ }[2]

Cf.

use feature qw{ say postderef };

$_ = [['a'], ['b'], ['c', 'd']];
say for @{ $_->[2] };
say for $_->[2]->@*;

$_ = \[ @$_ ];
say @$_ for @{ $$_ }[2];
say @$_ for $_->$*->[2];

Upvotes: 5

Sobrique
Sobrique

Reputation: 53508

Look at the -> operator. Likely the problem is the brackets. After all, when you say $$_[2] do you mean: ${$_}[2] or {$$_}[2].

Something like this is probably clearer (assuming you want the 1,2 and 8,9)

#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;

my @x = ( [ "a", "b", [ 1, 2 ], "c" ], 
          [ "x", "y", [ 8, 9 ], "z" ] );
my $y = \@x;

print Dumper $y;

foreach my $array_ref (@$y) {
    print Dumper $array_ref;
    my $z = $array_ref->[2];
    print "@$z\n";
}

Upvotes: 0

Related Questions