Reputation: 71
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
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
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