Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning Perl Web Development - From Novice To Professional (2006)

.pdf
Скачиваний:
57
Добавлен:
17.08.2013
Размер:
2.9 Mб
Скачать

330A 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