home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Book HomeLearning Perl, 3rd EditionSearch this book

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, though, this kind of loop is really a while loop in disguise, something like this:[223]

[223]Actually, 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 even before you read the comment. Before the loop starts, the control variable, $i, is set to 1. Then, the loop is really 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.

So, the first time through this loop, $i is 1. Since that's less than or equal to 10, we see the message. Although 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, so 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. Then $i is incremented to 10, which is less than or equal to 10, so 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. So 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 that it's easy for an experienced programmer to read that first line and say, "Ah, it's a loop that counts $i from one to ten."

Note that after the loop is done, the control variable has a value "after" the loop. That is, in this case, the control variable has gone all the way to 11.[224]

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

This loop is a very versatile loop, since you can make it count in all sorts of ways. This loop counts from -150 to 1000 by threes:[225]

[225]Of course, 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";
}

In fact, 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 (quite 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 really want one,[226] is with while:

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

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

Although C programmers are familiar with the first way, even a beginning Perl programmer should recognize that 1 is always true, making an intentional infinite loop, so the second is generally a better way to write it. 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 grammar, the keyword foreach is exactly 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 really a foreach loop:

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

That's really a foreach loop, but it's written for. Except for that one example, all through this book, we'll spell out foreach wherever it appears. But in the real world, do you think that Perl folks will type those extra four letters?[227] 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.

[227]If you think that, you haven't been paying attention. Among programmers, especially Perl programmers, laziness is one of the classical 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:[228]

[228]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. It's easy to get a so-called "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";
}


Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.