thrashbarg has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I recently read an interesting post (How can I add all the numbers in an array with out doing a foreach loop?) which had the following code snippet for taking the sum of an array:
@e = (1,2,3,4); my $foo; $foo += $_ for @e;
I was wondering if anyone can clarify the syntax for the loop used in this code? I understand what the code does but am unsure as to why/how. I have never seen a for loop like this before.

Replies are listed 'Best First'.
Re: For Syntax Question
by pg (Canon) on Jul 19, 2004 at 16:39 UTC

    Perlish! Just a style thing.

    That for is sort of modifier. It made you go through all elements of @a, and apply the operation to each of them.

    As if you are saying:

    @e = (1,2,3,4); my $foo; for (@e) { $foo += $_ } print $foo;
Re: For Syntax Question
by hardburn (Abbot) on Jul 19, 2004 at 16:40 UTC

    Run it through B::Deparse to see how perl sees it:

    $ perl -MO=Deparse -e '$foo += $_ for @e;' ; foreach $_ (@e) { $foo += $_; } -e syntax OK

    As the output shows, that line is exactly the same as if you had used foreach $_ (@e) { . . .. Taking the for to the end of the line just allows you to cram it into one statement, for better or worse.

    ----
    send money to your kernel via the boot loader.. This and more wisdom available from Markov Hardburn.

Re: For Syntax Question
by borisz (Canon) on Jul 19, 2004 at 16:40 UTC
    the code is the same as
    foreach $_ (@e) { $foo += $_; }
    the syntax is for all kind of oneliners like this
    $foo += $_ if $x < $foo;
    Boris
Re: For Syntax Question
by Limbic~Region (Chancellor) on Jul 19, 2004 at 16:43 UTC
    threshbarg,
    Larry's formal training makes him a linguist. One of the main design goals of Perl is so that it is a "natural" language. Basically that means you can write your code the way you might speak it. The two main ways of doing this is:
    • Do X for Y cases
    • For Y cases do X to each case

    The latter takes a block {} and can be very complex. The former needs to pretty much be a single statement. You can use the low precendence operators like and/or to link a few but you strike out when you try and put conditionals like if in there.

    So to answer your question: In each iteration of the loop, $_ (see perldoc perlvar) is replaced with the value (actually it is an alias) of the index being iterated over in @e. That value is being added to the current value of $foo

    Cheers - L~R

Re: For Syntax Question
by pbeckingham (Parson) on Jul 19, 2004 at 17:29 UTC

    The general form is:

    <statement> <modifier>
    and it is roughly equivalent to:
    <modifier> { <statement> }
    The modifiers can take the form of a conditional, or a looping construct:
    <statement> if $a > 1; <statement> unless $true;
    <statement> for @a; <statement> for 1..10; <statement> for keys %hash;
    The rule is that there can only be one modifier, so while there can be a complex logical condition, there cannot be two distinct conditions, or a mix of condition and loop. So the following are not valid:
    <statement> <modifier> <modifier> <statement> for @a unless $true;