Smartelf
Smartelf

Reputation: 879

what does $# accept as input in perl?

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

Answers (3)

ikegami
ikegami

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

Alan Haggai Alavi
Alan Haggai Alavi

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

zostay
zostay

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

Related Questions