Beginning Perl Web Development - From Novice To Professional (2006)
.pdf330A P P E N D I X ■ P E R L B A S I C S
until ($countdown <= 0) {
print "Counting down: $countdown\ n"; $countdown--;
}
And here’s what it produces:
$ perl until.pl Counting down: 5 Counting down: 4 Counting down: 3 Counting down: 2 Counting down: 1
$
The for Loop
Perl has a for loop, similar to the one found in C/C++/Java. Its syntax is
for (init_expr; test_expr; step_expr) { action
}
The init_expr is done first and once. Then the test_expr is tested to be true or false. If true, the action is executed, and the step_expr is executed. Then the test_expr is tested to be true or false, etc.
The most common use of a for loop is as an alternative way of writing a while loop that might resemble this one:
$i = 1;
while ($i <= 5) {
# do something important $i++;
}
This can be written in a for loop as follows:
for ($i = 1; $i <= 5; $i++) {
# do something important
}
The foreach Loop
Perl has another loop called the foreach loop. It is used to loop through lists and arrays. Arrays are discussed in detail in Beginning Perl, but since we have seen examples of a list, we can look at the foreach loop processing a list of numbers:
#!/usr/bin/perl -w
# foreach.pl
use strict;
A P P E N D I X ■ P E R L B A S I C S |
331 |
my $number;
foreach $number (1 .. 10) {
print "the number is: $number\ n";
}
The foreach loop executes the body of the loop (the print() function in this example) for each number in the list. $number is called the loop control variable, and it takes on the values in the list, one at a time. Recall that (1 .. 10) is shorthand for (1, 2, 3, 4, 5, 6, 7, 8, 9, 10). This code produces this result:
$ perl foreach.pl the number is: 1 the number is: 2 the number is: 3 the number is: 4 the number is: 5 the number is: 6 the number is: 7 the number is: 8 the number is: 9 the number is: 10
$
A note about the keywords for and foreach: they are synonyms for each other. In other words, we can write
foreach ($i = 1; $i <= 10; $i++)_ { .. }
and
for $number (1..10) { .. }
foreach is rarely used in place of for, but for is often used instead of foreach. In the spirit of minimal confusion, we will spell out foreach when we have a foreach loop.
do .. while and do .. until
When we were categorizing our lists, we divided indefinite loops into those that execute at least once and those that may execute zero times. The while loop we’ve seen so far tests the condition first, and so if the condition isn’t true the first time around, the “body” of the loop never gets executed. There are two other ways to write our loop to ensure that the body is always executed at least once:
do { action } while ( condition ); do { action } until ( condition );
Now we do the test after the block. This is equivalent to moving the diamond in our flowchart from the top to the bottom. Here is an example:
#!/usr/bin/perl -w
# dowhiledountil.pl
332A P P E N D I X ■ P E R L B A S I C S
use strict;
my $i = 1;
print "starting do...while:\ n"; do {
print " the value of \ $i: $i\ n"; $i++;
} while ($i < 6);
$i = 1;
print "starting do...until\ n"; do {
print " the value of \ $i: $i\ n"; $i++;
}until ($i >= 6);
Executing this program produces the following:
$ perl dowhiledountil.pl starting do...while:
the value of $i: 1 the value of $i: 2 the value of $i: 3 the value of $i: 4 the value of $i: 5
starting do...until the value of $i: 1 the value of $i: 2 the value of $i: 3 the value of $i: 4 the value of $i: 5
$
The importance of the do..while and do..until loop is that the body of the loop is always executed at least once.
Expression Modifying
As before, you can use while as a statement modifier. Following the pattern for if, here’s what you’d do with while:
while ( condition ) { statement }
becomes
statement while condition;
Similarly,
A P P E N D I X ■ P E R L B A S I C S |
333 |
becomes
statement until condition;
Therefore, this loop:
while (<STDIN>) {
print "You entered: $_";
}
can be written as
print "You entered: $_" while <STDIN>;
Loop Control Constructs
Perl provides constructs to allow us to control the flow of our loops. They allow us to break out of a loop, go to the next iteration of the loop, or re-execute the loop. We’ll start with breaking out of a loop.
Breaking Out
last, in the body of a loop, will make Perl immediately exit, or “break out of” that loop. The remaining statements in the loop are not executed, and you end up right at the end. Here is an example of a program that breaks out of the loop when the user enters the text done:
#!/usr/bin/perl -w
# last1.pl
use strict;
while (<STDIN>) {
if ($_ eq "done\ n") { last;
}
print "You entered: $_";
}
print "All done!\ n";
$ perl last1.pl
Songs
You entered: Songs from
You entered: from the
You entered: the
Wood
You entered: Wood
334A P P E N D I X ■ P E R L B A S I C S
done
All done!
$
You can use a last in any looping construct (while, until, for, and foreach). However, the last does not work with the do { } while or do { } until loops.
Note that last1.pl could have been written using an expression modifier. It can be argued that this code is a bit more readable:
#!/usr/bin/perl -w
# last2.pl
use strict;
while (<STDIN>) {
last if $_ eq "done\ n"; print "You entered: $_";
}
print "All done!\ n";
Going On to the Next
If you want to skip the rest of the processing of the body, but don’t want to exit the loop, you can use next to immediately go execute the next iteration of the loop by testing the expression. Here is an example of a program that reads input from the user, and if the line of input is not blank, the line is printed. It the line is blank, then we immediately go back to read the next line:
#!/usr/bin/perl -w
# next1.pl
use strict;
print "Please enter some text:\ n"; while (<STDIN>) {
if ($_ eq "\ n") { next;
}
chomp;
print "You entered: [$_]\ n";
}
Here is an example of running this program in Windows:
$ perl next1.pl
Please enter some text: testing
You entered: [testing] one
A P P E N D I X ■ P E R L B A S I C S |
335 |
two three
You entered: [two three]
^Z<enter>
$
Notice that when the user entered a blank line, then the program immediately read the next line of input.
This program could have be written with an expression modifier:
#!/usr/bin/perl -w
# next2.pl
use strict;
print "Please enter some text:\ n"; while (<STDIN>) {
next if $_ eq "\ n"; chomp;
print "You entered: [$_]\ n";
}
Reexecuting the Loop
On rare occasions, you’ll want to go back to the top of the loop, but without testing the condition (in the case of a for or while loop) or getting the next element in the list (as in a for or while loop). If you feel you need to do this, the keyword to use is redo. This is illustrated in this example:
#!/usr/bin/perl -w
# redo.pl
use strict;
my $number = 10;
while (<STDIN>) { chomp;
print "You entered: $_\ n"; if ($_ == $number) {
$_++; redo;
}
print "Going to read the next number now...\ n";
}
If the user enters the value 10, then the input is incremented to 11 and we jump to the beginning of the block, at which point the value will be chomped (which has no effect on the value since it does not end in newline), and then the value 11 is reported. Executing this program in Windows would look like the following:
336A P P E N D I X ■ P E R L B A S I C S
$ perl redo.pl
5
You entered: 5
Going to read the next number now...
20
You entered: 20
Going to read the next number now...
10
You entered: 10 You entered: 11
Going to read the next number now...
^Z<enter>
$
Loop Labels
By default, last, next, and redo operate on the innermost looping construct only. For instance, in this code:
#!/usr/bin/perl -w
# looplabel1.pl
use strict;
my $i = 1;
while ($i <= 5) { my $j = 1;
while ($j <= 5) { last if $j == 3;
print "$i ** $j = ", $i ** $j, "\ n"; $j++;
}
$i++;
}
the last statement within the innermost loop construct (while ($j <= 5)) will last out of the innermost looping construct only. Therefore, each time $j reaches 3 within the inner loop, we last out of the inner loop, increment $i, and go back up to test the expression for the outer while loop. This generates the following output:
$ perl looplabel1.pl 1 ** 1 = 1 2 ** 1 = 2 2 ** 2 = 4 3 ** 1 = 3 3 ** 2 = 9 4 ** 1 = 4 4 ** 2 = 16
A P P E N D I X ■ P E R L B A S I C S |
337 |
5 ** 1 = 5
5 ** 2 = 25
$
To make the last statement last out of the outer looping construct, we must label the outer looping construct with a loop label. A loop label is a variable that the programmer creates (it is recommended that you use all uppercase names), followed by a colon, preceding the looping construct. This is illustrated in looplabel2.pl:
#!/usr/bin/perl -w
# looplabel2.pl
use strict;
my $i = 1;
OUTER: while ($i <= 5) { my $j = 1;
while ($j <= 5) {
last OUTER if $j == 3;
print "$i ** $j = ", $i ** $j, "\ n"; $j++;
}
$i++;
}
Now, when the last statement is executed, the code jumps out of the outer loop named
OUTER:
$ perl looplabel2.pl 1 ** 1 = 1 2 ** 1 = 2
$
goto
As a matter of fact, you can put a label before any statement whatsoever. If you want to really mess around with the structure of your programs, you can use goto LABEL to jump anywhere in your program. Whatever you do, don’t do this. This is not to be used. Don’t go that way.
We’re telling you about it for the simple reason that if you see it in anyone else’s Perl, you can laugh heartily at them. goto with a label is to be avoided like the plague.
Why? Because not only does it turn the clock back 30 years (the structured programming movement started with the publication of a paper called “Use of goto considered harmful”), but it tends to make your programs amazingly hard to follow. The flow of control can shoot off in any direction at any time, into any part of the file—maybe into a different file. You can even find yourself jumping into the middle of loops, which really doesn’t bear thinking about. Don’t use it unless you really, really, really understand why you shouldn’t. And even then, don’t use it. Larry Wall has never used goto with a label in Perl, and he created Perl.
Don’t. (He’s watching.—Ed.)
338 A P P E N D I X ■ P E R L B A S I C S
Summary
This appendix contains lightly edited excerpts from Beginning Perl, Second Edition by James Lee (Apress, 2004; ISBN: 1-59059-391-X), the goal being to give you a refresher on some of the basics of Perl. There are still many aspects of Perl you should cover, including many more detailed within Beginning Perl that were used in this book. For example, Chapter 4 contains coverage of lists and arrays, Chapter 5 works with hashes, and Chapter 6 describes subroutines and functions. Not to mention the nine other chapters of introductory material on Perl. Beginning Perl is a great companion to this book; if you still need assistance with Perl,
I recommend picking up a copy of Beginning Perl.
Index
■Symbols
" " (double quotes), 290, 299
# (hash sign), 242–243 #! (shebang line), 202 $ character
escaping with INTERPOLATE enabled, 242 scalar variables and, 306
$dbh, 53
$DBI::errstr method, 55 $m, 276
$r, 276
% (wildcard host entry), 59 %>, 273
%] tag, 240 %ENV hash, 23
& (AND) operator, 296, 321 && operator, 301
&> tag, 273
*(multiplication operator), 292, 294
**(exponentiation operator), 295 ++ (autoincrement operator), 308 ' ' (single quotes), 288
-- (autodecrement operator), 308 / (divide operator), 294
:all group, 6
; (semicolon), 8
< (less-than sign), 74, 299 <%, 273
<%perl%> block, 269, 273 <& tag, 273
<=> operator, 300–301
<= (less-than-or-equal-to sign), 300 = (assignment operator), 308, 310 == (comparison operator), 299
> (greater-than sign), 74, 299
>= (greater-than-or-equal-to sign), 300 >> (double greater-than sign), 74
! operator, 301 [% tag, 240, 298
\t escape sequence, 288 ^ (XOR) operator, 297
_request() method, 210, 211 _ (underscore), 245
| (pipe) character, 85, 86 as OR operator, 297, 321
|| operator, 301
~ (NOT) operator, 298
■A
accessing request headers, 217–220 AND (&) operator, 296–297, 321 Apache::Constants class, 221–222 Apache::Cookie class
methods and parameters, 222 reading cookies, 224–225 sending cookies with, 223
Apache::DBI module, 207–208 Apache::Log module, 227–229 Apache::PerlRun program
about, 189
Apache::Registry vs., 189–193, 202–205 clearing namespaces with, 189, 203 enabling, 205
invoking PerlRunOnce option, 206 using with PerlHandler, 202
Apache::Registry program about, 189
Apache::PerlRun vs., 189–193, 202–205 configuring to mod_perl, 206–207 renaming of, 201
using with PerlHandler, 202 Apache::Request module
looking at parameters with param() method, 217
need for when compiling Mason, 265 working with uploaded files, 78, 225–226
Apache::Server module, 226–227 Apache::SOAP package, 148 Apache::Template module, 240 Apache::Upload module, 225–226 Apache. See also mod_perl module
accessing request headers, 217–220 building and installing mod_perl, 194–197 child processes for, 184, 186
compatible versions of, 4–5 configuring mod_perl before using,
198–199
disabling unneeded modules, 195 executing mod_perl module with
Apache::Registry or Apache::PerlRun, 189–193, 202–205
forking, 186–187
getting information about server, 226–227 implementing SOAP server with, 148 Mason configurations with, 267–269
339