[za-pm] 0..$#input_numbers ???

Anne Wainwright anotheranne at fables.co.za
Wed Apr 21 11:25:35 PDT 2010


Hello, Nick,

Thanks for the input which has cleared the air, couple of comments
below.

On Wed, 21 Apr 2010 06:12:42 +0200
Nick Cleaton <nick at cleaton.net> wrote:

> Note: Beware! Default reply-to is to the list.
> On Tue, 2010-04-20 at 23:25 +0200, Anne Wainwright wrote:
> 
> > As usual, writing a clear email about a problem has wrung most of
> > the answer out of the apparent fog. Nevertheless ....
> > 
> > >From page 59 of INTERMEDIATE PERL (alpaca book)
> > 
> > 1 my @input_numbers = (1, 2, 4, 8, 16, 32, 64);
> > # $len = @input_numbers;
> > 2 my @indices_of_odd_digit_sums = grep {
> > 3    my $number = $input_numbers[$_];
> > 4    my $sum;
> > 5    $sum += $_ for split //, $number;
> > 6    $sum % 2;
> > 
> > 7 } 0..$#input_numbers;  # OR 0..$len;
> 
> Not quite - $#input_numbers is the index of the last element in
> @input_numbers, whereas $len is the number of elements in
> @input_numbers.  Since arrays are indexed starting from 0,
> $#input_numbers is one less than $len.

Yes, I see that. Perl gracefully does not complain if you specify more
elements than are actually in the array with $len.

I found a reference to $#ARGV in PROGRAMMING PERL so at least I see it
in print - important for me at this stage).


> 
> > 
> > 8 print "\n\t the input nos. @input_numbers";
> > 9 print "\n\t the index nos. @indices_of_odd_digit_sums of the
> >   odd_digit_sums\n\n";
> > 
> > 
> > >From line 7, just where does the syntax of $#input_numbers come
> > >from?
> > <Notes, not $#$input_numbers  as I might have expected in my
> > innocence>
> 
> You don't have a $input_numbers variable there, you have an
> @input_numbers array.
> 
> The way $#array works is that you replace the @ at the start of the
> array name with $# to get the index of the last element.

That is the whole nub of the matter, i had never seen this syntax
previously. Useful but odd. 

> 
> > The only ref to $# that I find is a deprecated alternative to printf
> > listed in LEARNING PERL (2nd edn. p.134). This evaluates to the same
> > as my $len but must be the only place in perl where # is anything
> > other than a comment marker.
> 
> The deprecated $# variable has nothing to do with the $#array syntax.
> $#array is not deprecated, it's the right thing to use here.
> 
> > I can uncomment the line after line 1 and replace the syntax as
> > commented on line 7, which would be my way and it works fine
> > 
> > 0..$input_numbers also works but, as you would know, generates minor
> > warnings.
> 
> 0..$input_numbers isn't doing what you think - there is no
> $input_numbers anywhere else in your example.  $input_numbers will
> evaluate to 0 (with a warning) because it's an uninitialised variable,
> and you'll run the inner code just once rather than once for each
> array element.

My error, should have said @input_numbers which perl evaluates in a
scalar context & does the right thing, under protest.

> 
> This is one of the reasons to get into the habit of starting your
> scripts with
> 
> use strict;
> use warnings;

I'll do that. I always use the -w switch, but am unsure if it is the
same as  'use warnings;'. I can see that 'use strict;' is something
else entirely.

> 
> ... as these make it harder to write a script that seems to work but
> isn't really doing what you think it's doing.
> 
> 
> Nick


More information about the Za-pm mailing list