1. Trang chủ
  2. » Công Nghệ Thông Tin

Beginning Perl Third Edition PHẦN 3 docx

46 562 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 46
Dung lượng 366,19 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

64 exit; } Notice that in each if statement we execute the exit function since, if the condition is true, there is no reason to check any of the following conditions.. An indefinite l

Trang 1

#!/usr/bin/perl

# walking.pl

use warnings;

use strict;

print "What's the weather like outside? ";

chomp(my $weather = <STDIN>);

print "How hot is it, in degrees? ";

chomp(my $temperature = <STDIN>);

print "And how many emails left to reply to? ";

chomp(my $work = <STDIN>);

if ($weather eq "snowing") {

print "It's snowing, let's go!\n";

} elsif ($weather eq "raining") {

print "No way, sorry, it's raining so I'm staying in.\n";

Trang 2

63

Let’s say it is 201

degrees, we’ve got 27 e-mails to reply to, and it’s cloudy out there:

$ perl walking.pl

What's the weather like outside? cloudy

How hot is it, in degrees? 20

And how many emails left to reply to? 27

Well, why not?

$

Looks like we can fit a walk in after all

The point of this rather silly little program is that once it has gathered the information it needs, it

runs through a series of tests, each of which could cause it to finish First, we check to see if it’s snowing:

if ($weather eq "snowing") {

print "It's snowing, let's go!\n";

If so, then we print our message and, this is the important part, do no more tests If not, we move on

to the next test:

} elsif ($weather eq "raining") {

print "No way, sorry, it's raining so I'm staying in.\n";

Again, if this is true, we stop testing; otherwise, we move on Finally, if none of the tests are true, we

get to the else:

} else {

print "Well, why not?\n";

}

Please remember that this is very different from what would happen if we used four separate if

statements The tests overlap, so it is possible for more than one condition to be true at once For

example, if it was snowing and we had over 30 emails to reply to, we’d get two conflicting answers elsif

tests should be read as “Well, how about if ?”

Now let’s update the program we saw earlier, guessnum1.pl, to use if/elsif/else The decision we made in the first version was implemented with three if statements:

Trang 3

64

exit;

}

Notice that in each if statement we execute the exit() function since, if the condition is true, there

is no reason to check any of the following conditions Instead of using the exit() function in each of the

if blocks, this would be better written with an if/elsif/else, as shown in guessnum2.pl:

print "Guess my number!\n";

print "Enter your guess: ";

my $guess = <STDIN>;

if ($target == $guess) {

print "That's it! You guessed correctly!\n";

} elsif ($guess > $target) {

print "Your number is more than my number\n";

} elsif ($guess < $target) {

print "Your number is less than my number\n";

}

The unless Statement

There’s another way of saying if (not $a) As always in Perl, there’s more than one way to do it.2

Trang 4

65

Expression Modifiers

When we talk in English, it’s quite normal to say

• If this is not true, then this happens, or

• Unless this is true, this happens

And it’s also quite natural to reverse the two phrases

• This happens if this is not true, or

• This happens unless this is true

In Perl-speak, we can take this if statement:

if ($number == 0) {

die "can't divide by 0";

}

and rewrite it as follows:

die "can't divide by 0" if $number == 0;

Notice how the syntax here is slightly different, it’s action if condition There is no need for

parentheses around the condition, and there are no curly braces around the action Indeed, the

indentation isn’t part of the syntax, so we can even put the whole statement on one line Only a single

statement will be covered by the condition This form of the if statement is called an expression

you may find it more natural to write this:

die "\$name has a false value" unless $name;

Using Short-Circuited Evaluation

There is yet another way to do something if a condition is true By using the fact that Perl stops

processing a logical operator when it knows the answer, we can create a sort of unless conditional:

$name or die "\$name has a false value";

How does this work? Well, it relies on the fact that Perl uses short-circuited, or lazy, evaluation to

give a logical operator its value If we have the statement X or Y, then if X is true, it doesn’t matter what

Y is, so Perl doesn’t look at it If X isn’t true, Perl has to look at Y to see whether or not that’s true So if

Trang 5

66

$name has a true value, then the die() function will not be executed Instead, Perl will do nothing and

continue on to execute the next statement

This form of conditional is most often used when checking that something we did succeeded or returned a true value We will see it often when we’re handling files

To create a positive if conditional this way, use and instead of or For example, to add one to a

counter if a test is successful, you can say

$success and $counter++;

As you’ll recall, and statements require both substatements to be true So, if $success is not true, Perl won’t bother evaluating $counter++ and upping its value by 1 If $success is true, then it would

or the heat death of the universe occurs, whichever comes first

There’s also a difference between definite loops and indefinite loops In a definite loop, you know in

advance how many times the block will be repeated An indefinite loop will check a condition in each iteration to determine whether it should loop again

There’s also a difference between an indefinite loop that checks before the iteration, and one that checks afterward The latter will always go through at least one iteration, in order to get to the check, whereas the former checks first and so may not go through any iterations at all

Perl supports ways of expressing all of these types of loops First, let’s examine the while loop

The while Loop

Let’s start with indefinite loops These check a condition, then do an action, then go back and check the

condition again We’ll look first at the while loop As you might guess from the name, this type of loop keeps doing something while a condition is true The syntax of while is much like the syntax of if:

while ( condition ) { action }

Once again, those curly braces are required Here’s a very simple while loop:

Trang 6

Let’s see a flow chart for this program While there’s still a value greater than 0 in the $counter

variable, we do these two statements:

print "Counting down: $countdown\n";

$countdown ;

Perl goes through the loop a first time when $countdown is 5; the condition is met, so a message is

printed and $countdown gets decreased to 4 Then, as the flow chart illustrates, back we go to the top of the loop We test again: $countdown is still more than 0, so off we go again Eventually, $countdown is 1, we print our message, $countdown is decreased, and now it’s 0 This time around, the test fails, and we exit

the loop

while (<STDIN>)

Recall that we talked about using <STDIN> to read from standard input (normally the keyboard) This

statement reads the next line of standard input, up to and including the newline character:

$line_in = <STDIN>;

Trang 7

68

We can put this assignment within a while loop that will read from standard input until end of file (in Unix a ^D, or the Ctrl and D keys pressed at the same time; in Windows a ^Z<enter>) This loop reads a line at a time into $line_in and then prints that line:

while ($line_in = <STDIN>) {

print $line_in;

}

This behavior, reading from standard input until end of file, is so common that if <STDIN> is by itself within the while loop parentheses (and only within the while loop parentheses), then the line of

standard input is magically assigned to the special variable $_ This loop reads each line into $_, and then

the line is printed:

Let’s look at an example of using this magic variable $_ This program will loop through standard

input one line at a time until end of file, and for each line it will print a message followed by the line entered:

Trang 8

69

Note In Unix, end of file is ^D (Control-D) In Windows, end of file is ^Z<ret> (yes, you have to type the return key) You will have to adjust the example above if you are working in Windows

The $_ variable is very useful—it is the default argument for many different functions, such as the

chomp() function The statement

chomp $_;

could have been written as

chomp;

Many Perl programmers find it convenient and readable to write a loop like this one:

while ($line = <STDIN>) {

Whether or not you write code to take advantage of the magic nature of $_ is up to you, but we

suggest you practice with it enough to be able to read code that others have written using $_

Infinite Loops

The obvious but important point is that what we’re testing gets changed inside the loop If our condition

is always going to give a true result, we have an infinite loop Let’s just remove the second of those two statements:

Trang 9

70

$countdown never changes It’s always going to be 5, and 5 is, we hope, always going to be more than

0 So this program will keep printing its message until you interrupt it by holding down Ctrl and D Hopefully, you can see why you need to ensure that what you do in your loop affects the condition Should we actually want an infinite loop, there’s a fairly standard way to do it Just put a true value—

typically 1—as the condition:

while (1) {

print "Bored yet?\n";

}

The converse, of course, is to say while (0) in the loop’s declaration, but nothing will ever happen

because this condition is tested before any of the commands in the loop are executed A bit silly really

Trang 10

71

Note The negation of > is <=, not < Yes, we have made the same mistake many times.…

The for Loop

Perl has a for loop, similar to the one found in C, C++, and Java Its syntax is

for (init_expression; test_expression; step_expression) {

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, then the step_expr is executed Then the test_expr is tested to be true or false, and so

on

The most common use of a for loop is as an alternative way of writing a while loop that might

resemble this one:

This can be written in a for loop as

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 We will talk

about arrays in the next chapter, but since we have seen examples of a list, we can look at the foreach

loop processing a list of numbers:

Trang 11

72

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) The following 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

This accomplishes two things: first, it satisfies use strict; since $number gets declared with my(), and second,

it lexically scopes $number to the body of the foreach (it is not available outside the looping construct)

A note about the keywords for and foreach: they are synonyms for each other In other words, we

We will talk more about foreach in the next chapter when we discuss the array data type

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,

Trang 12

73

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 flow chart from the top to the bottom

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 loops is that the body of the loop is always executed

at least once

Trang 13

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 that let us control the flow of our loops They allow us to break out of a loop, go

to the next iteration of the loop, or reexecute the loop We’ll start with breaking out of a loop

Trang 14

Note that last1.pl could have been written using an expression modifier It can be argued that this

code is a bit more readable:

print "All done!\n";

Going On to the Next

If you want to skip the rest of the processing of the body on the current iteration, 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, the program immediately goes back to read the next line:

Trang 15

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, as illustrated in this example:

Trang 17

78

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 and increment $i, then go back up to test the expression for the outer while loop This generates

the following output:

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

Trang 18

79

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

It is highly recommended that you don’t use this construct Really, we mean it Don’t use it Caveat

emptor

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 “Go To Statement Considered Harmful”), but it tends to

make your programs incredibly 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

Summary

Before this chapter, our programs plodded along in a straight line, one statement followed by another We’ve now seen how we can react to different circumstances in our programs, which is the start of

flexible and powerful programming We can test whether something is true or false using if and unless,

and take appropriate action

We’ve also examined how to test multiple related conditions using elsif We can repeat areas of a program, in several different ways, using while, until, for, and foreach Finally, we’ve examined some ways to alter the flow of Perl’s execution through these loops We can break out of a loop with last, skip

to the next element with next, and start processing the current element again with redo

Exercises

1 Modify the number-guessing program guessnum2.pl so that it loops until the

correct answer is entered

2 Write a program that prints the squares of the numbers between 1 and 10

3 Write a program to print all the numbers between 1 and 50 that are evenly

divisible by 5 Loop by 1, not by 5!

Trang 20

■ ■ ■

81

Lists and Arrays

In Chapter 2 we introduced the idea of a scalar, which is a single value—a number or string Having the ability to work with numbers and strings, and having scalar variables into which we can store numbers and strings is nice—this allows us to write programs to manipulate data However, because they can

contain only a single value, scalars are somewhat limited

There are times we want to group information together or express correspondences between

information Just like the ingredients in a recipe or the pieces in a jigsaw, some things belong together in

a natural sequence: for example, individual lines in a file, or the names of players in a volleyball

tournament In Perl, we represent these relationships in lists—series of scalars Lists can be stored in

another type of variable called an array, and we call each piece of data in the list an element

In this chapter, we’ll see how to create and work with lists We’ll also take another look at the

foreach loop, which enables us to step through lists and arrays

Lists

We’re all familiar with lists from everyday life Think about a grocery store shopping list: what properties does it have? First of all, it’s a single entity, one piece of paper Second, it’s made up of a number of

values In the case of a shopping list, you might want to say that these values are actually strings—

“potato chips”, “Guinness”, “cheese”, and so on Finally, it’s also ordered, which means that there’s a

first item and a last item

Lists in Perl aren’t actually much different; they’re counted as a single unit, though they’re made up

of a number of values In Perl, these values are scalars, rather than purely strings, and they’re stored in the order they appear in the list

We’ll specify lists in our program code as literals, just like we did with strings and numbers And

we’ll be able to perform certain operations on them Let’s begin by looking at a few simple lists and how

to create them

Trang 21

82

Simple Lists

The simplest shopping list is one that contains nothing at all1

Similarly, the simplest list in Perl has no

elements in it, and it is called the empty list Here’s what it looks like:

As you can see, we have created two lists, one containing a number, and one containing a string—so

far so good Remember the print() function? It treats its arguments as lists, and the magic about functions like print() that treat their arguments as lists is that you can omit the parentheses Saying print "cheese" is just the same as saying print("cheese") So now we know that what we give to print()

is really a list, and we’re allowed to leave out the parentheses if we wish

From this, we should be able to work out how to put multiple values into a list When we said

zeroth element is "Hello ", the first is "world", and the second is "\n" Now, let’s do that again with

numbers instead of strings:

Trang 22

83

As before, Perl doesn’t automatically put spaces between list elements for us when it prints them

out, it just prints them as it sees them Similarly, it doesn’t put a newline on the end for us2 There’s

nothing special about lists from that point of view; if we want to add spaces and newlines, we need to

put them into the list ourselves

More Complex Lists

We can also mix strings, numbers, and variables in our lists Let’s see an example of a list with several

different types of data Although this isn’t very different from what we were doing with print() in

Chapter 2, this example reinforces the idea that lists can contain any scalar literals and scalar variables

So, type this in, and save it as mixedlist.pl:

Notice that the print() function prints a list of six elements, including literal strings, literal

numbers, and a scalar variable for good measure

Trang 23

One last thing to note is that Perl automatically flattens lists That is, if you try putting a list inside

another list, the internal list loses its identity In effect, Perl removes all the parentheses apart from the outermost pair There’s no difference at all between any of these three lists:

(3, 8, 5, 15)

((3, 8), (5, 15))

(3, (8, 5), 15)

Similarly, Perl sees each of these lists exactly the same as the others:

('one', 'two', 'three', 'four')

(('one', 'two', 'three', 'four'))

('one', ('two', 'three'), 'four')

(('one','two'), ('three', 'four'))

So we can say that in Perl all lists (and all arrays) are one-dimensional

Creating Lists Easily with qw//

Perl provides a useful operator that lets us easily create lists of one-word strings The operator is qw//,

which stands for quote words It is related to the other “q” operators we saw in Chapter 2: q// and qq//

The qw// operator takes all the items within the slashes that are separated by whitespace characters and

creates a single-quoted list of them For instance, this code:

Ngày đăng: 09/08/2014, 14:21

TỪ KHÓA LIÊN QUAN