Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

demystify

0 views
Skip to first unread message

Vishnu

unread,
Dec 21, 2009, 4:56:01 PM12/21/09
to begi...@perl.org
I was going through the book intermediate perl and came across the
following code.

my @odd_digit_sum = grep digit_sum_is_odd($_), @input_numbers;

sub digit_sum_is_odd {
my $input = shift; ------------> what are we doing here?
my @digits = split //, $input; # Assume no nondigit
characters
my $sum;
$sum += $_ for @digits; ---------> what exactly is the
operation performed here? specially haven't understood "for"
return $sum % 2;
}

Appreciate your inputs.

+Vishnu

Erez Schatz

unread,
Dec 22, 2009, 6:29:43 AM12/22/09
to begi...@perl.org
A pox on gmail's "reply" not sending to list.

2009/12/22 Erez Schatz <moon...@gmail.com>:
> 2009/12/21 Vishnu <chada...@gmail.com>:


>> I was going through the book intermediate perl and came across the
>> following code.
>

> I'm not familiar with the scope of Intermediate Perl, but from your
> questions it would seem that you should've started with Learning Perl.
> At any rate, both lines you highlight include "perl idioms", i.e.
> usage of syntax that is immediately recognised by any programmer
> sufficiently fluent in the language.


>
>>        my $input = shift;  ------------> what are we doing here?
>

> a bare shift performs a shift()
> (http://perldoc.perl.org/functions/shift.html) action on the default
> array, which inside a sub is made of all the parameters that have been
> passed to the sub. In this case, the function is digit_sum_is_odd($_),
> meaning $_ is the parameter passed on to digit_sum_is_odd(). the first
> line is assigning the parameter to $input.
>
> The actual reasoning behind this can be found here:
> http://perldoc.perl.org/perlsub.html, and, most likely, in Learning
> Perl.


>
>>        $sum += $_ for @digits;  ---------> what exactly is the
>

> In Perl, we pride ourself that There Is More Than One Way To Do It.
> And this often means that there is more than one way to write stuff in
> a way that makes more sense in the context of the specific line. This
> line basically means "iterate over all items in the array @digits, and
> add them to $sum", and is a way more simple way of writing:
>
> for (my $i; $i < @digits; i++) {
>    $sum += $digits[$i];
> }
>
> At any rate, it appears that Intermediate Perl does assume a certain
> familiarity with Perl idioms, so you may encounter many more of these
> throughout it. I do suggest getting Learning Perl, at least as a
> reference for these.

--
Erez

"The government forgets that George Orwell's 1984 was a warning, and
not a blueprint"
http://www.nonviolent-conflict.org/ -- http://www.whyweprotest.org/

John W. Krahn

unread,
Dec 22, 2009, 11:48:51 AM12/22/09
to Perl Beginners

If you start out with the array:

my @input_numbers = ( 123, 234, 345, 456 );

Then the expression:

my @odd_digit_sum = grep digit_sum_is_odd($_), @input_numbers;

Will pass each element of @input_numbers in turn to the
digit_sum_is_odd() subroutine and if the subroutine returns TRUE will
then pass that element on through to the @odd_digit_sum array. In the
end the @odd_digit_sum array will contain the elements 234 and 456.


The first line of the subroutine:

my $input = shift;

Is short for:

my $input = shift @_;

Because in a subroutine the arguments to a subroutine are passed through
the @_ array and shift() removes the first element of that array and
returns it which is then assigned to the $input variable.


my @digits = split //, $input;

This converts, for example, the number 123 to the string '123' and
splits it into individual characters '1', '2' and '3' and assigns that
list to the array @digits.


my $sum;

This creates a lexically scoped variable which is only visible inside
the subroutine.


$sum += $_ for @digits;

This uses the _for_ statement modifier, which is similar to the
_foreach_ loop:

foreach ( @digits ) {
$sum += $_;
}

This loops over the elements of @digits and assigns each element in turn
to the $_ variable. Each element in turn is then added to the $sum
variable. So, for example, if @digits contains ( '1', '2', '3' ) then
the sum of those digits is 6.


return $sum % 2;

Finally modulus is performed on the $sum value. $sum % 2 will return 0
(FALSE) if $sum is divisible by 2 (even) or 1 (TRUE) if $sum is NOT
divisible by 2 (odd).

John
--
The programmer is fighting against the two most
destructive forces in the universe: entropy and
human stupidity. -- Damian Conway

0 new messages