Section 10.7. The for Control Structure


10.7. The for Control Structure

Perl's for control structure is like the common for control structure you may have seen in other languages such as C. It looks like this:

     for (initialization; test; increment) {       body;       body;     } 

To Perl, this loop is a while loop in disguise, something like this:[*]

[*] The increment happens in a continue block, which is beyond the scope of this book. See the perlsyn manpage for the truth.

     initialization;     while (test) {       body;       body;       increment;     } 

The most common use of the for loop, by far, is for making computed iterations:

     for ($i = 1; $i <= 10; $i++) {  # count from 1 to 10       print "I can count to $i!\n";     } 

When you've seen these before, you'll know what the first line is saying before you read the comment. Before the loop starts, the control variable, $i, is set to 1. Then, the loop is a while loop in disguise, looping while $i is less than or equal to 10. Between each iteration and the next is the increment, which here is a literal increment, adding one to the control variable, which is $i.

The first time through this loop, $i is 1. Since that's less than or equal to 10, we see the message. Though the increment is written at the top of the loop, it logically happens at the bottom of the loop after printing the message. So, $i becomes 2, which is less than or equal to 10; we print the message again, and $i is incremented to 3, which is less than or equal to 10, and so on.

Eventually, we print the message that our program can count to 9; $i is incremented to 10, which is less than or equal to 10. We run the loop one last time and print that our program can count to 10. Finally, $i is incremented for the last time, to 11, which is not less than or equal to 10. Control drops out of the loop, and we're on to the rest of the program.

All three parts are together at the top of the loop, so it's easy for an experienced programmer to read that first line and say, "Ah, it's a loop that counts $i from 1 to 10."

After the loop is done, the control variable has a value "after" the loop. In this case, the control variable has gone all the way to 11.[*] This loop is versatile, since you can make it count in all sorts of ways. For example, we can count down from 10 to 1:

[*] Obligatory This is Spinal Tap outdated pop-culture reference.

     for ($i = 10; $i >= 1; $i--) {       print "I can count down to $i\n";     } 

And this loop counts from -150 to 1000 by threes:[]

] It never gets to 1000 exactly. The last iteration uses 999 since each value of $i is a multiple of three.

     for ($i = -150; $i <= 1000; $i += 3) {       print "$i\n";     } 

You could make any of the three control parts (initialization, test, or increment) empty if you wish, but you still need the two semicolons. In this unusual example, the test is a substitution, and the increment is empty:

     for ($_ = "bedrock"; s/(.)//; ) {  # loops while the s/// is successful       print "One character is: $1\n";     } 

The test expression (in the implied while loop) is the substitution, which will return a true value if it succeeded. In this case, the first time through the loop, the substitution will remove the b from bedrock. Each iteration will remove another letter. When the string is empty, the substitution will fail, and the loop is done.

If the test expression (the one between the two semicolons) is empty, it's automatically true, making an infinite loop. But don't make an infinite loop like this until you see how to break out of such a loop, which we'll discuss later in this chapter:

     for (;;) {       print "It's an infinite loop!\n";     } 

A more Perl-like way to write an intentional infinite loop, when you want one,[] is with while:

] If you somehow made an infinite loop thats gotten away from you, see whether Ctrl-C will halt it. It's possible that you'll get a lot of output after typing Ctrl-C, depending upon your system's I/O and other factors. Hey, we warned you.

     while (1) {       print "It's another infinite loop!\n";     } 

Though C programmers are familiar with the first way, even a beginning Perl programmer should recognize that 1 is always true, so the second is generally a better way to write an intentional infinite loop. Perl is smart enough to recognize a constant expression like that and optimize it away, so there's no difference in efficiency.

10.7.1. The Secret Connection Between foreach and for

It turns out that inside the Perl parser the keyword foreach is equivalent to the keyword for. That is, any time Perl sees one of them, it's the same as if you had typed the other. Perl can tell which you meant by looking inside the parentheses. If you've got the two semicolons, it's a computed for loop (like we've just been talking about). If you don't have the semicolons, it's a foreach loop:

     for (1..10) {  # Really a foreach loop from 1 to 10       print "I can count to $_!\n";     } 

That's a foreach loop, but it's written for. Except for that one example, we'll spell out foreach wherever it appears throughout this book. In the real world, do you think that Perl folks will type those extra four letters?[*] Excepting only beginners' code, it's always written for, and you'll have to do as Perl does and look for the semicolons to tell which kind of loop it is.

[*] If you think that, you haven't been paying attention. Among programmers, especially Perl programmers, laziness is one of the classic virtues. If you don't believe us, ask someone at the next Perl Mongers' meeting.

In Perl, the true foreach loop is almost always a better choice. In the foreach loop (written for) in that previous example, it's easy to see at a glance that the loop will go from 1 to 10. But do you see what's wrong with this computed loop that's trying to do the same thing? Don't peek at the answer in the footnote until you think you've found what's wrong:[]

] There are two and one-half bugs. First, the conditional uses a less-than sign, so the loop will run nine times instead of ten. Its easy to get a "fencepost" bug with this kind of loop, like what happened when the rancher needed enough fenceposts to make a 30-meter-long fence with a post every three meters. (The answer is not ten fenceposts.) Second, the control variable is $i, but the loop body is using $_. And second and a half, it's a lot more work to read, write, maintain, and debug this type of loop, which is why we say that the true foreach is generally a better choice in Perl.

     for ($i = 1; $i < 10; $i++) {  # Oops! Something is wrong here!       print "I can count to $_!\n";     } 



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