Reputation: 81
I have a Perl reference to a hash $conf
that has an array as one of the values. I can retrieve it by:
$conf->{group}->{names} # returns an array (NOT array ref)
But when I store it in some other variable I get this unusual behaviour.
say ($conf->{group}->{names}); # some array ref
say ($conf->{group}->{names}[1]); # some string
my @list = $conf->{group}->{names};
say ($list[0]); # same array ref
What may be the reason for this behaviour? I want to loop over this array but using foreach
but unable to do so because of this.
I wish to iterate over the elements of the array, but I can't figure out how.
Upvotes: 0
Views: 68
Reputation: 385897
You claim $conf->{group}->{names}
is an array as opposed to a reference to one, but that's impossible. Hashes values are scalars; they can't be arrays. This is why we store references to arrays in hashes.
That $conf->{group}->{names}[1]
works (short for $conf->{group}->{names}->[1]
) indicates $conf->{group}->{names}
it's an a reference to an array.[1]
You assign this reference to the @list
, and therefore populate @list
with this reference. This is why $list[0]
is this reference.
You wish to iterate over the elements of the array. If you had a named array, you would use
for (@array) {
...
}
But you have a reference to an array. There are two syntaxes that can be used to accomplish that.
The circumfix syntax features a block that returns the reference
for (@{ $ref }) { # Or just @$ref when the block contains a simple scalar.
...
}
In your case,
my $ref = $conf->{group}{names}[1];
for (@$ref) {
...
}
or
for (@{ $conf->{group}{names}[1] }) {
...
}
The postfix (aka "arrow") syntax features can be tacked onto an expression.
for ($ref->@*) {
...
}
In your case,
my $ref = $conf->{group}{names}[1];
for ($ref->@*) {
...
}
or
for ($conf->{group}{names}[1]->@*) {
...
}
->@*
requires Perl 5.24+. It's available in Perl 5.20+ by adding both use feature qw( postderef );
and no warnings qw( experimental::postderef );
, or by adding use experimental qw( postderef );
. This is safe because the then-experimental feature was accepted into Perl without change.
See Perl Dereferencing Syntax and the documentation linked by it.
use strict;
as you always should.Upvotes: 7