|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59
|
|
Chapter 5:
|
|
|
|
Building Blocks
|
|
It has long been an axiom of mine
that little things are infinitely the most important.
|
|
- Sir Arthur Conan Doyle, The Adventures of Sherlock Holmes
|
|
Part I of this book provided a gentle introduction to programming theory
and philosophy. Part II expands on those concepts by introducing the Perl
language, one step at a time.
|
|
There are many ways to introduce a new programming language. We could
simply provide a reference guide to the various commands, along with the
online manual pages, and let you puzzle things out on your own. If you're a
person who prefers this method of learning, our language guide is in Part
IV, Reference, and the online documentation is extensive. Have fun!
|
|
Alternatively, we could start to write a simple program, expanding on it
and adding more features as we learn more about the language. This is one
of the most popular ways of teaching a language. Unfortunately, the result-
ing program can become complex rather quickly, and often seems artificial.
|
|
A third method employs many small examples of various aspects of the
language; each example is self-contained and easily understandable. As
new features are discussed, they become part of future examples, but no
example contains language features that have not yet been discussed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The resulting bits of code may work together as part of a larger program, but
no attempt is made for that program to do anything useful.1
|
|
This last method is the one we are using in Part II. Each of our examples
demonstrates a feature of MacPerl. Each is self-contained and should run if
you want to try it out. Some of our examples may not produce output, but
they should not produce errors, either.2
|
|
In summary, rather than trying to build one complete program by the end of
Part II, we provide you with the tools and understanding to leverage our
examples into any number of programs of your own.
|
|
The goal of Part II is to provide you with the basic skills for writing Perl
scripts, and to give you an understanding of Perl which will enable you to
move forward and learn more. We won't try to teach you everything there
is to learn about programming Perl (Perl is big!) but we hope that you'll
leave Part II with a good understanding of what Perl can offer.
|
|
Many of the examples in this chapter build on concepts covered in Part I of
this book. If you find yourself getting lost, or don't think that we're provid-
ing sufficient explanation for a new idea, please go back to the early chap-
ters and look through them again.
|
|
A journey of a thousand miles must begin with a single step.
|
|
Chinese proverb
|
|
Perl is a language, much like other languages you may be familiar with. As
a programming language, it has much in common with other programming
languages such as AppleScript, awk, or C. It was invented by humans, so it
also has a lot in common with other human languages, such as English or
mathematical (e.g., algebraic) notation.
|
|
Languages tend share certain syntactic elements. These elements combine,
like building blocks, to form larger structures. Most languages have nouns,
verbs, expressions, statements, and punctuation - although these may go by
different names in different languages. Perl's building blocks may not be
|
|
|
|
1Many years ago, young girls who were learning embroidery skills would create
pieces composed of the stitches they had learned. The resulting "samplers"served to
demonstrate examples of particular stitches. In a similar fashion, the programs we will
present in this chapter serve as a sampler of Perl code.
2Unless, of course, we're teaching you about errors!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
immediately familiar to you, but they are analogous to similar elements in
other languages.
|
|
Literals - Numbers And Strings
|
|
We will begin very simply.
|
|
3
3.14159
three
|
|
We can describe the valuesshown above in several ways.33is a number,
specifically, an integer. 3.14159is also a number, in this case a floating
pointnumber. threeis a character string, or, more simply, a string.
|
|
Each of these is also a literal, (specifically, a numeric literal or string
literal) because its value is literally what is shown. Literals are distin-
guished from variables, whose value may vary.4Literals are some of the
nouns, or objects, in the Perl language.
|
|
When used in Perl, strings are usually quoted(e.g., delimited by either sin-
gle or double quotes5). Strings which contain whitespace(e.g., blanks or
tabs), or characters with special meaning to Perl, must bequoted. Numbers,
in contrast, are never quoted - if quoted, they are converted to strings.
|
|
Variables
|
|
Literals are very useful, but they are not very flexible. As we saw in the
boiled egg example in chapter 2, we can use variables in a program to repre-
sent values that could change, such as cooking time, temperature, number of
eggs, and so on. Variable names are composed of alphanumeric characters
(letters and digits) or underscores, _. They must begin with a letter or an
underscore.6
|
|
|
|
3One way is to call them values.
4We don't expect the value of 3 to change anytime soon.
5The type of quote mark has an effect on how the contents of the string will be
evaluated or interpolated. More on this shortly.
6Some specialvariable names are defined and mayinclude a character that is not
alphanumeric (e.g., $#) or may be comprised only of digits (e.g. $1). These variables are
not user-defined (although you may modify their values). In general, the rule is:begin
your variable names with a letter or _and stick to alphanumeric characters!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Variables are also used as they are in algebra, to hold the value of an
expression. We'll cover expressions later in this chapter.
|
|
A scalarvariable contains a singlevalue; the value can be either a number
or a string.7Scalar variable names are always preceded by a dollar sign, $.
|
|
$cook_minutes = 3;
$some1 = 'Vicki';
$pi = 355/113;
|
|
A string can be coerced(converted) into a number and vice-versa. This may
sound a bit silly, but it turns out to be very handy on occasion. The rules for
coercion are basically what you would expect:
|
|
$s = '123';
$n = $s * 2;
$s = "$s $n";
|
|
|
|
# e.g., 246
# e.g., '123 246'
|
|
Exercise caution however, when working with anything other than simple
integers. What you expect may not be what you get!8
|
|
An arrayvariable can contain multiple(zero or more) values. Array
variable names are always preceded by an at sign, @.
|
|
@colors = ('red', 'green', 'blue');
|
|
Because the initial character ($or @) identifies the type of variable, it is
perfectly legal for a scalar variable to have the same name as an array
variable! This can actually be quite useful, once you get over the shock.
|
|
Case - A Sensitive Issue
|
|
Unlike some operating systems, such as Unix and VMS, the Mac OS is not
case sensitive.9Upper- and lower-case letters are usually considered to be
identical; the letter ais treated the same way as the letter A. If you create
a file on your Macintosh named MyStuffand later try to create a file named
|
|
|
|
7A scalar can also hold a reference.
8See Unreal Numbers, by Tom Phoenix, in The Perl Journal, issue #8 (vol. 2, no. 4),
Winter, 1997.
9URLs (Uniform Resource Locators) are a bit schizophrenic on this issue. Everything
up to the first slash is case-insensitive; everything thereafter is (generally) sensitive to
case differences (unless, of course, the server is a Macintosh!).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mystuff, you will usually receive an Alert dialog (or possibly overwrite the
MyStufffile!)
|
|
Perl, on the other had, iscase sensitive. This means that in Perl (and thus
in MacPerl!), the letter ais notthe same as the letter A. So, $cook_time
and $Cook_Timeare two separate and distinct variables.
|
|
If you are only familiar with the Mac OS, case sensitivity may be a strange
concept. Be sure to keep it in mind as you work in MacPerl, however, and be
sure to specify your variable names consistently!
|
|
Note: The usual Perl convention is to use lower case for most ordinary
user-defined variable names. For complex names, some people prefer
mixed case (e.g., $loopCounter), but with the first character of the
name in lower case. Alternatively, the underscore may be used (e.g.,
$loop_counter) to separate portions of a variable name.
|
|
Special variables, such as environment variables(e.g., $USER), Perl
built-in variables($MATCH), and special constructs such as filehandles
(STDIN) andlabels(LOOP1), are generally named entirely in upper case
to alert readers to their special nature.10
|
|
Quoting
|
|
As we said previously, strings are usually quoted. Perl has several different
ways to perform quoting. The simplest way is to use either single, ', or dou-
ble, ", quote marks.11Under many circumstances, the result will be the same
whichever you choose. However, there are special circumstances where the
choice of quote is important.
|
|
Perl supports variable interpolation; interpretation of a variable within
(in general) a text string. Double quotes permit variable interpolation to
occur. Single quotes suppress variable interpolation. For instance:
|
|
$fruit = 'apple';# set to string apple
$price = '$1.00';# set to string $1.00
$cost = "$1.00";# evaluate the variable $1!
|
|
|
|
10Note that the MacOS toolbox calls follow their own case conventions, and
MacPerl's Mac::toolbox modules follow suit....
11A number of fancy quoting mechanisms (e.g., q/string/) were introduced in Perl
version 5. See Part IV,Reference, for more details.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$cake = 'pine$fruit';# set to string pine$fruit
$cake = "pine$fruit";# set to string pineapple
$pie = "$fruitpie";# evaluates $fruitpie!
$pie = "${fruit}pie";# set to string applepie
|
|
The last two examples show what can happen when a scalar variable is
embedded in a "word". If Perl disagrees with you about where the variable
stops and the rest of the word begins, you will get strange results. By enclos-
ing the variable name in braces (a form of quotation), you can specify where
the variable stops and the rest of the word begins.12
|
|
Double quotes also permit backslash (i.e., escape sequence) interpretation.
Again, single quotes suppress this interpretation. We'll come back to escape
sequences when we discuss the printcommand, later in this chapter.
|
|
Take care to consider which type of quote to use. For string literals, we rec-
ommend using single quotes unless you have a reason for doing otherwise. In
certain cases, such as print statements, you may find that you have a good
reason more often than not. The best rule is: Think Before You Quote!
|
|
Operators
|
|
Operatorsoperate on data elements (e.g., variables and literals), combining
and modifying those elements in various ways. Perl has several hundred
operators, many of which can be used in more than one way!13
|
|
By way of introduction, this section will cover the most common arithmetic
and string operators. As we work our way through the examples in Part II,
we will introduce additional operators as needed. For a more comprehen-
sive treatment of Perl operators, be sure to check the Referenceportion of
this book (Part VI), the online help, or Programming Perl.
|
|
Arithmetic Operators
|
|
Let's start with the most common arithmetic operators; these should be
largely familiar to you already.
|
|
|
|
12You only need the braces if the characters following the variable name are alphanu-
meric (letters or numbers) or underscore. However, you are always free to enclose the
variable name in braces, if this makes your meaning more clear.
13Perl takes a rather casual approach to the use of such terms as operator, function,
and subroutine. You will find that these terms are frequently used interchangeably, or
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+
-
*
/
=
|
addition
subtraction
multiplication
division
assignment
|
|
Note that Perl, like most programming languages, uses *for multiplication.
Here are two additional operators whose symbols may be less familiar.
|
|
**
%
|
exponentiation
modulus (remainder)
|
|
The first one, **, is the power or exponentiationoperator (e.g., 10**3is
the Perl way of writing 103). Don't be confused by %- it's not percentage as
you might think! Rather, it is the modulus(integer remainder) operator.
The value of the arithmetic expression
|
|
11 % 5
|
|
would be 1(11divided by 5leaves an integer remainder of 1). Modulus is
the only arithmetic operator that performs calculations in integer mode;
floating point is the default for all others.14
|
|
Shortcut Assignment
|
|
Suppose we wanted to write a Perl expression to increment a counter by 10.
We could say
|
|
$counter = $counter + 10;
|
|
This is a common operation, however, and Perl has shortcuts for many
common operations. A simpler way to write this expression would be
|
|
$counter += 10;
|
|
By mixing the various numeric calculation operators with the assignment
operator, we can derive a collection of "shortcut" assignment operators.
|
|
+=
-=
*=
|
"increment by"
"decrement by"
"multiply by"
|
|
|
|
14It is possible to reset the default for all operations to integer calculation by includ-
ing the pragma, useinteger, in your program. Generally, however, it is best to use
the int()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/=
%=
**=
etc.
|
"divide by"
"modulo by"
"raise to the power"
|
|
Each of these shortcut operators works in a similar fashion. For example:
|
|
$x -= 5;
$y *= 100;
|
# $x = $x - 5;15
# $y = $y * 100;
|
|
There are more than a dozen of these shortcut assignment operators; we'll
cover more of them as we go along ...
|
|
Because in Perl, There's More Than One Way To Do It, there are even
shorter shortcuts for increment and decrement, a pair of very common opera-
tions. These are the autoincrement, ++, and autodecrement, --, operators,
created for the specific case when the value of a variable is incremented (or
decremented) by exactly 1. The following commands are thus equivalent:
|
|
$x = $x + 1;
$x += 1;
$x++;
|
|
Numeric Comparison
|
|
The comparison operators should also be familiar to you, although some of
these may look a little bit different from when you saw them in math class.
(!is Perl's "not" operator).
|
|
<
>
<=
>=
!=
==
|
less than
greater than
less than or equal to
greater than or equal to
not equal to
equal to (equality)
|
|
Be sure to note the difference between the =(assignment) operator and the
==(equality) operator. The former, =, is used to assign a value to a varia-
|
|
|
|
15Using comments to "explain" idioms is generally not a good idea. If you don't expect
a reader of your code to understand the idiom, perhaps you should use clearer code! In
general, comments should be used to explain high-level intent, abstract algorithms, data
formats, and the like; they should complement the code rather than reiterate it. In other
words, avoid putting comments such as this one into realcode.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ble (or list of variables). The latter, ==, is used to compare two expressions.
For instance, using the assignment operator, we might say:
|
|
$dozen = 12;
|
|
This assigns the value, 12, to the scalar variable named $dozen. It does not
make any comparisons. Let's say that we wanted to keep adding eggs until
we had 12 eggs in the pan. Using the equality operator, we could ask the
question, does the number of eggs equal 12?
|
|
if ($eggs == 12) ...
|
|
This fragment of code compares the value of the variable $eggsto the
number 12 and tests for equality. One of the most common Perl programming
mistakes, however, is to use the assignment operator, =, where you meant to
use the equality comparison operator, ==, or vice versa, as:
|
|
if ($eggs = 12) ...
|
|
Rather than testing whether the current value of $eggsis 12, this code sets
the value of $eggsto 12, then tests the "truth" of the resulting expression
(12). In Perl, non-zero numbers are always considered to be "true", so the if
will always succeed, regardless of how many eggs there really are!
|
|
Note:You might think of ==as "really equals", or remember that the
equality comparison operator, ==, is the opposite of inequality, !=. Or,
you may think of some other way to recall the difference between ==
and =.But find a way to remember!
|
|
String Operators
|
|
Although arithmetic operations are more common, Perl also has operators
which work specifically on strings. Several of these are analogous to the
numeric operations.
|
|
x
.
|
repeat by
concatenate with
|
|
The xoperator is the string repetitionoperator.16The statement
|
|
$ohs = 'o' x 5;
|
|
is equivalent to
|
|
|
|
16This is somewhat analogous to "multiplication" for a character string.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$ohs = 'ooooo';
|
|
The .operator (dot) is used for string concatenation. The statement
|
|
$bf = 'butter' . 'flies';
|
|
sets the variable $bfto the string 'butterflies'.
|
|
The string comparison operators act very similarly to their arithmetic
counterparts; they are distinguished, however, by alphabetic (string)
names (i.e., the numeric <operator corresponds to the string ltoperator).
|
|
lt
gt
le
ge
ne
eq
|
less than
greater than
less than or equal to
greater than or equal to
not equal to
equal to
|
|
Note that each operator is abbreviated from its full English name.
|
|
String comparison is based on (ASCII17) character ordering. The following
are some examples of string comparison expressions.
|
|
'abc' eq 'abc'# the strings are identical
'ABC' ne 'abc'# remember about case sensitivity
'four' lt 'three' # f precedes t in the alphabet
|
|
When you are performing a comparison, be sure to use the correct (string or
numeric) operators, depending on the type of data you are comparing. If you
forget and choose the wrong operators, Perl will not complain, but the pro-
gram's results may not be what you expected!
|
|
Precedence
|
|
Precedencerules determine the order in which operations will take place.
You may recall from elementary school arithmetic that multiplication
takes precedence over addition. That is, the following equation
|
|
17 + 2 * 5
|
|
is arithmetically equivalent to
|
|
|
|
17American Standard Code for Information Interchange. There are alternative ways of
ordering characters, which are less dependent upon a particular alphabet. However,
these are not currently used by Perl.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 + 10
|
# not 19 * 5
|
|
because the multiplication is performed before the addition. Parentheses
can be used to make precedence rules clearer
|
|
17 + (2 * 5)
|
# still 17 + 10
|
|
or to overridethem
|
|
(17 + 2) * 5
|
# now 19 * 5
|
|
Perl has a very large and complex list of precedence rules.18Even if you
have an excellent memory (and an interest in learning the entire list!), we
recommend that you use parentheses to avoid difficulty.Youmay be able to
remember all of the precedence rules, but the parentheses could help some-
one else, if they need to read and/or maintain your code.
|
|
Expressions
|
|
We have referred to expressionsseveral times now. In English, an expres-
sion is a "particular word, phrase, or form of words". In programming lan-
guages, expressions have a similar meaning.
|
|
Expressions are composed of Perl syntactic elements, such as literals, vari-
ables, operators, etc. An expression can be used wherever a value can be;
that is, an expression can be evaluatedto produce a value.
|
|
In the simplest case, an expression contains only one element, as in the case
of the (literal) number 3. Sometimes the expression contains several ele-
ments and must be evaluated further. The numeric expression below
|
|
355/113
|
|
consists of two integer numeric literals (355and 113) and the division
operator, /. This expression, discovered by Chinese mathematicians,
evaluates to a rather close approximation (3.1415929...) of Pi.
|
|
Expressions must be legal within the syntax of a specific language. The text
|
|
If dog rabbit.
|
|
is not a valid English sentence, even though it is composed of valid English
syntactic elements (words and punctuation). Similarly, the following lines
|
|
|
|
18The complete precedence table is provided in Part IV, Reference.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
are not valid Perl expressions, even though they are composed of valid Perl
syntactic elements.
|
|
123 $i
123 ++ $i
$j * 123 + $i)
|
|
Statements
|
|
Before a Perl expression can be used, it must be incorporated into a state-
ment.19A statement is a command to the Perl interpreter, (generally)
telling it to do something. To ensure that Perl knows where one statement
stops and another begins, statements make use of punctuation, much as
human languages do.
|
|
Perl statements end with a semicolon, ;20. Statement blocksare enclosed in
braces, {}. Commentsbegin with a hash mark, #, also known as a pound
sign or sharp sign, and finish at the end of the line.21Programmers include
comments solely for the benefit of human readers; Perl itself ignores them.
|
|
Statements are composed of expressions, blocks, and other statements, with
comments scattered among them. Taken together, this collection of state-
ments comprises your program.
|
|
Commands: Operators, Functions, And More
|
|
Once you have some objects (variables, literals, and operators) gathered
together into expressions and statements, you need to tell Perl what to do
with them. You do this by using commands, the verbs of the Perl language.
|
|
Perl, like many programming languages, is rather terse. If you were talking
to a friend, you might say "Write the word 'hello', please." In Perl, you
issue a command:
|
|
print "hello\n";
|
|
|
|
19To be precise, Perl also makes use of declarations, which look a lot like statements,
but act a bit differently. A declaration tells Perl about something, but doesn't specify
what to do with it; a statement tells Perl what to do.
20As with most rules, there are exceptions. For instance, no semicolon is required at
the end of a block or a program. However, we advise that you put one in anyway...
21Comments don't require a semicolon either. (Picky; picky...)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The printcommand writes a string of characters, in this case "hello", to
the screen (the MacPerl output window). The odd looking pair of characters
at the end of the string, \n, is an escape sequence22representing a newline.
It tells Perl to move to a new line after printing (the equivalent of pressing
return when you are typing text on a keyboard). This is often useful to keep
what is printed from bumping into whatever comes next.23
|
|
Note that we enclosed the string "hello\n"in double quotes. As we
discussed earlier, single quotes would have prevented the \n from being
interpreted as a newline. Try
|
|
print 'hello\n';
|
|
to see what happens.
|
|
There are many commands in Perl and they fall into various categories
depending on certain attributes. One such category is operators, as intro-
duced earlier. Much of the Perl language is made up of operators. Some of
these are made up of symbols, as we have seen; others look like words.
|
|
Perl has more than four dozen named unary operators(e.g., defined, exit,
log, sleep, and sqrt). A unary operator takes a single argument. Named
unary operators have (relatively)memorable names, rather than symbolic
representations.
|
|
Perl also has named list operators, which can take a list (i.e., multiple
values), as an argument. In the preceding example, printis a list operator
(although there is only one item in its argument list). Try
|
|
print 'hello', "\n";
|
|
Then there are functions. A function is a self-contained piece of a program
that performs a specific task. Functions can take arguments and usually
return a result. A function is calledby the main program (or another func-
tion). Its arguments are passedto it, normally enclosed in parentheses.
|
|
|
|
22\nis one of a class of multi-character codes called escape sequences. (The backslash
character, \, is also called the escape character). Escape sequences provide a short-
hand way to describe special characters (e.g.,tabs or newlines) or groups of charac-
ters (e.g., all digits or any white space character).
23The Macintosh actually uses a Carriage Return (^M or octal \015) rather than a
Line Feed (^J or octal \012) as the "end of line" character. To help ensure the porta-
bility of Perl programs, MacPerl uses the \n construct, but actually reads and writes
Carriage Returns rather than the Line Feeds that Unix Perl would use.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Some languages make distinctions between different types of functions, such
as proceduresor subroutines.24Perl, however, employs a very liberal defini-
tion of the term function. A function acts upon its input, returning some sort of
result. Perl commands can all, essentially, be thought of as functions. If it
looks like a function, it is a function.
|
|
What makes something "look like a function"? Traditionally, a function is
called by enclosing its arguments within parentheses. So, a functionis a list
or named unary operator, with parentheses around its arguments.
|
|
Unfortunately, things aren't quite that simple. Recall the discussion of
precedence earlier in this chapter. By enclosing a function's arguments in
parentheses, you raise their precedence. So, results may vary if you use the
parentheses or leave them out; that is, "functions" and "operators" may not
always act in quite the same way. When in doubt,use parentheses.25
|
|
To summarize
|
|
Most functions take one or more arguments. If more than one argument is
expected, the order is usually important. Arguments are generally separa-
ted by commas.26
|
|
rename("myfile", "yourfile"); # rename a file
|
|
Many functions returna value which may be saved in a variable or used in
any other expression.
|
|
$sq = sqrt($x)
|
# sqrt returns the square root
|
|
Functions may be used with or without the enclosing parentheses. If paren-
theses are omitted, the function acts like a list operatoror a unary operator.
These operators follow precedence rules which determine how they will
act. As we discussed previously, precedence rules are complex. To be abso-
lutely certain how a function will act, you should use parentheses.
|
|
|
|
24Whereas the built-in functions are also known as operators, user-defined functions
are frequently referred to as subroutines.
25In part II of this book, our examples use Perl functions with parentheses. However,
you should expect to see our coding style become somewhat less rigid in part III, as we
attempt to show you more "real world" examples. In particular, printstatements are
frequently written without the enclosing parentheses.
26If one of the arguments is a filehandle, it should not be followed by a comma. File-
handles will be discussed in the next chapter.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Control Flow
|
|
As we discussed in Part I, the structure of a program can be described by
three simplecontrol flowconstructs:
|
|
-
sequence - a sequence of individual statements, taken in order
|
|
-
selection - a decision or selection, made between one or more choices
|
|
-
repetition - the same action, performed a specified number of times
|
|
Each of these constructs, spearately or in combination, can be used to control
the flow of the program.
|
|
Sequence
|
|
Sequences are the simplest form of control flow. Any series of statements,
taken in order, comprises a sequence.
|
|
$x = 25;
sleep($x);
print "$x";
$x -= 5;
|
|
Selection
|
|
Selection tells the program to choose from among alternatives27. Depending
upon the choice that is made, a different block of code will be executed. In
previous sections, we introduced a control flow construct that is used for
selection: the ifstatement. This statement is used to make a decision - the
program checks for a certain conditionand performs some actionif the
condition is true.28This type of control flow construct is also often referred
to as a conditionalstatement.
|
|
if ($x == 25) {
sleep($x);
print($x);
}
|
|
Often, decisions are more complex. For example, you may want to perform
one action if the condition is true and a different action if the condition is
false. Our egg cooking example contained this set of instructions:
|
|
|
|
27Often including the alternative of doing nothing at all!
28Note that Perl, unlik some languages, requires the action to be in a block.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
If an egg is cracked, discard it.
|
|
Otherwise (if it is not cracked), put the egg into the pan.
|
|
Here is an example that might come up in "real" code. Suppose you have a
program which counts how many mice are connected to your Macintosh and
prints the result.29Being a careful programmer, you want to be sure the mes-
sage is grammatically correct.
|
|
if ($count == 1) {
print("My Mac has 1 mouse.\n")
}
if ($count != 1) {
print("My Mac has $count mice.\n")
}
|
|
Just as English has the word "otherwise" which is equivalent to "if the
previous condition is not true", Perl has the elsestatement. The above
code fragment could thus be made simpler (and more efficient), as follows:
|
|
if ($count == 1) {
print("My Mac has 1 mouse.\n")
} else {
print("My Mac has $count mice.\n")
}
|
|
Alternatively, you could instead use unless.
|
|
unless ($count == 1) {
print("My Mac has $count mice.\n")
} else {
print("My Mac has 1 mouse.\n")
}
|
|
The decision to use an ifor an unlessstatement is based on how you think
about the problem you are solving. By expressing the control flow as simply
and naturally as possible, you will make things easier for the next person
(perhaps yourself!) who looks at the code.30
|
|
|
|
29Admittedly, you probably won't write many programs to count mice. But programs
which count things and generate reports are relatively common.
30Just to prove TMTOWTDI, you might also consider the ?:conditionaloperator (a
handy shortcut!). See chapter 9, Odd Corners, for an example.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
So far, we have selected between two choices (a Booleanchoice). The
condition either is met or is not met. But we could also have several choices.
|
|
if ($count == 1) {
print("My Mac has 1 mouse.\n")
}
elsif ($count > 1) {
print("My Mac has $count mice.\n")
}
elsif ($count == 0) {
print("How do you run a Mac with no mice?\n")
}
else {
print("Eeek! Negative mice found?!\n")
}
|
|
You can include as many elsifstatements as you need. Use care if the
conditions are not exclusive; only the first condition which is true will be
executed. The elseblock will be executed only if no prior conditions are
met. A final elsecondition is commonly included to catch errors.31There is
no multiple choice equivalent for unless.
|
|
Repetition
|
|
The third control flow construct is repetition. Using repetition, a section of a
program repeats an action or sequence of actions whilesome condition is
true (or untila condition becomes true). These sections of repeating code
are called loops, because the control loops through them some number of
times.
|
|
The code fragment below implements a simple egg timer. It sleeps for 60
seconds, then increments (bumps) a counter. The counter is set (initialized)
to 1 before we begin the timing loop.
|
|
$n = 1;# start with counter set to 1
while ($n < 4) {# Loop while $n is less than 4
print("tick\n");
sleep(60);# sleep 1 minute
$n++;# increment the counter
}
print("RRIINNGG\n");
|
|
|
|
31For example, conditions you didn't think of or conditions that should not happen.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
After each pass through the sequence of statements, the program returns to
the topof the loop and checks the condition again: is the value of $nstill
less than 4? The block of code (called a while loop) repeats 3 times, once
each for values of 1, 2, and 3. When $nbecomes 4, the condition ($n < 4)
is no longer true, so the loop terminates(stops repeating).
|
|
Again, you have a choice in how to state the condition, depending upon how
you think about the problem. The following is an equivalent timing loop.
|
|
$n = 1;# start with counter set to 1
until ($n == 4) {# Loop until $n equals 4
print("tick\n");
sleep(60);# sleep 1 minute
$n++;# increment the counter
}
print("RRIINNGG\n");
|
|
This time, the loop continues untilthe condition is true.
|
|
Putting the pieces together
|
|
Once you have sequence, selection, and repetition, you can combine these
co
|