Reputation: 879
I have had this question for a while.
Assuming I have a simple array,
my @arr;
foreach my $i (0..$#arr){
print "\$arr[$i] = '$arr[$i]'\n";
}
$#arr simply returns the last index of the array
however, what happens if I want to use it for something more complex like?:
foreach my $i (0..$#@{$someHash{$}[$b]{$c}});
sure, I can write it as
foreach my $i (0..(scalar(@{$someHash{$}[$b]{$c}})-1));
But that just makes the code even more complex.
So my question is, can the $# be used for anything else other than a simple array( references, a list returned from a function call, etc...) and if so, how?
Thanks
Upvotes: 3
Views: 112
Reputation: 386406
If it's
$#array
for an array, it's
$#{ $array_ref }
for a reference. Of course, it can be any expression that returns an array reference, so you want the following:
$#{ $someHash{$}[$b]{$c} }
See Mini-Tutorial: Dereferencing Syntax
Upvotes: 0
Reputation: 74262
Yes, it can be done:
sub foo {
return { 'bar' => { 'array' => [ 'qux', [qw/ has three elements /] ] } };
}
print $#{ foo->{'bar'}->{'array'}->[1] }; # 2
When writing such code, my thought process is: get to the array with the @{}
syntax and then replace @
with $#
.
Upvotes: 2
Reputation: 4005
Yes, you want:
for my $i (0..$#{$some_hash{$a}[$b]{$c}}) { ... }
If possible, though, I generally prefer
for my $value (@{ $some_hash{$a}[$b]{$c} }) { ... }
an index value is rarely as useful as the value stored in the array. Typically, if I need both, I add a counter instead:
my $i = 0;
for my $value (@{ $some_hash{$a}[$b]{$c} }) { ... } continue { $i++ }
and for clarity, I will also pre-assign the complex variable in the loop:
my $i = 0;
my $widget_list = $some_hash{$a}[$b]{$c};
for my $value (@{ $widget_list }) { ... } continue { $i++ }
Just because you can do some things in one line in Perl doesn't necessarily mean you should.
Upvotes: 4