Section 3.6. The foreach Control Structure


3.6. The foreach Control Structure

It's handy to be able to process an entire array or list, so Perl provides a control structure to do that. The foreach loop steps through a list of values, executing one iteration (time through the loop) for each value:

     foreach $rock (qw/ bedrock slate lava /) {       print "One rock is $rock.\n";  # Prints names of three rocks     }

The control variable ($rock in that example) takes on a new value from the list for each iteration. The first time through the loop, it's "bedrock"; the third time, it's "lava".

The control variable is not a copy of the list elementit actually is the list element. That is, if you modify the control variable inside the loop, you'll be modifying the element in the original list, as shown in the following code snippet. This is useful and supported, but it would surprise you if you weren't expecting it.

     @rocks = qw/ bedrock slate lava /;     foreach $rock (@rocks) {       $rock = "\t$rock";       # put a tab in front of each element of @rocks       $rock .= "\n";           # put a newline on the end of each     }     print "The rocks are:\n", @rocks; # Each one is indented, on its own line

What is the value of $rock after the loop has finished? It's the same as it was before the loop started. The value of the control variable of a foreach loop is automatically saved and restored by Perl. While the loop is running, there's no way to access or alter that saved value. So after the loop is done, the variable has the value it had before the loop or undef if it didn't have a value. That means that if you want to name your loop control variable "$rock", you don't have to worry that maybe you've used that name for another variable.

3.6.1. Perl's Favorite Default: $_

If you omit the control variable from the beginning of the foreach loop, Perl uses its favorite default variable, $_. This is (mostly) like any other scalar variable, except for its unusual name, as in this example:

     foreach (1..10) {  # Uses $_ by default       print "I can count to $_!\n";     }

Though this isn't Perl's only default by a long shot, it's Perl's most common default. You'll see many other cases in which Perl automatically uses $_ when you don't tell it to use some other variable or value, thereby saving the programmer from the heavy labor of having to think up and type a new variable name. Not to keep you in suspense, one of those cases is print, which prints $_ if given no other argument:

     $_ = "Yabba dabba doo\n";     print;  # prints $_ by default

3.6.2. The reverse Operator

The reverse operator takes a list of values (which may come from an array) and returns the list in the opposite order. If you were disappointed that the range operator, .., only counts upward, this is the way to fix it:

     @fred   = 6..10;     @barney = reverse(@fred);  # gets 10, 9, 8, 7, 6     @wilma  = reverse 6..10;   # gets the same thing, without the other array     @fred   = reverse @fred;   # puts the result back into the original array

The last line is noteworthy because it uses @fred twice. Perl always calculates the value being assigned (on the right) before it begins the actual assignment.

Remember that reverse returns the reversed list; it doesn't affect its arguments. If the return value isn't assigned anywhere, it's useless:

     reverse @fred;         # WRONG - doesn't change @fred     @fred = reverse @fred; # that's better

3.6.3. The sort Operator

The sort operator takes a list of values (which may come from an array) and sorts them according to the internal character ordering. For ASCII strings, that would be ASCIIbetical order. Of course, ASCII is a strange place where all of the capital letters come before all of the lowercase letters, where the numbers come before the letters, and the punctuation marks are here, there, and everywhere. But sorting in ASCII order is the default behavior; you'll see in Chapter 13 how to sort in whatever order you'd like:

     @rocks   = qw/ bedrock slate rubble granite /;     @sorted  = sort(@rocks);        # gets bedrock, granite, rubble, slate     @back    = reverse sort @rocks; # these go from slate to bedrock     @rocks   = sort @rocks;         # puts sorted result back into @rocks     @numbers = sort 97..102;        # gets 100, 101, 102, 97, 98, 99

As you can see from that last example, sorting numbers as if they were strings may not give useful results. But, of course, any string that starts with 1 has to sort before any string that starts with 9, according to the default sorting rules. And like what happened with reverse, the arguments themselves aren't affected. If you want to sort an array, you must store the result back into that array:

     sort @rocks;          # WRONG, doesn't modify @rocks     @rocks = sort @rocks; # Now the rock collection is in order



Learning Perl
Learning Perl, 5th Edition
ISBN: 0596520107
EAN: 2147483647
Year: 2003
Pages: 232

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net