Perl Program Flow: Conditionals and Loops
April 26, 1999
By default, Perl programs, like many other languages, execute
in the order the code is written, from top to bottom. This
order of execution is known as "program flow" in
textbooks, and there are a variety of reasons why we might
want to alter the program flow under certain circumstances.
Again, consider the parallels to real life -- you may plan
out your day in a certain order, but variable circumstances
may change this order. For instance, your day plan might look
like:
if (bank is open)
{ go to bank }
else
{ go to grocery;
go to bank }
The use of conditional logic allows your schedule to become
more flexible -- go to the bank first if it is open, otherwise
go to the grocery and then go to the bank. Similarly, we apply
the same sort of logic to the flow of Perl programs. The two
main controls which alter program flow are conditionals and
loops.
Conditionals, like the if...else statement seen in the
above example, determine what actions to take when certain
conditions are met or are not met.
Loops are used to repeat one or more actions a certain number
of times based upon certain conditions.
if and unless statements
One of the most intuitive conditionals is the if
statement. You can read this example aloud to make the logic
perfectly clear:
if (some condition)
{ ...do some actions when true... }
Notice that the actions clause is enclosed within curly braces.
A set of curly
braces is known as a statement block, and any number of
Perl statements
can appear here, separated by semicolons. Recalling our currency
conversion
example, we can output a message sensitive to which currency is
more valuable
than the other:
if ($USTotal>$CDNTotal)
{ print "Presently, the US dollar is ".
"worth more than the Canadian dollar.\n" }
The else clause of an if statement lets you
define a statement block in case the conditional test is false:
if ($USTotal>$CDNTotal)
{ print "Presently, the US dollar is ".
"worth more than the Canadian dollar.\n" }
else
{ print "Presently, the Canadian dollar is ".
"worth more than the US dollar.\n" }
Unfortunately, the above example is flawed. It is theoretically
possible that both currencies are of equal value. The
elsif clause acts as a combined else and if
clause, allowing an else clause which tests an additional
condition. This may be clearer by example:
if ($USTotal>$CDNTotal)
{ print "Presently, the US dollar is ".
"worth more than the Canadian dollar.\n" }
elsif ($USTotal==$CDNTotal)
{ print "Presently, both the US dollar and ".
"the Canadian dollar are of equal value.\n" }
else
{ print "Presently, the Canadian dollar is ".
"worth more than the US dollar.\n" }
|
|
Note the way the output strings have been broken up into multiple segments.
Although we could have simply typed one long line, it would have been difficult
to read within this article. To make the line more legible, the output string
has been broken into portions, with a concatenation operator,
the ".", between each
portion. The result is exactly the same as if we typed one long line.
|
The statement above actually tests two conditions: if the
US dollar is worth more then the first message is output;
if the two are equal then the second message is output; the
process of elimination tells us that if neither of these
were true than the US dollar must be worth less, so the third
message it output.
A few notes on syntax: the formatting and indentation used
in these examples is merely one style, albeit a style this
author finds intuitive and legible. Other programmers may
favor different styles of indentation -- Perl is very flexible
and essentially lets you format statements and statement blocks
any way you like. Also, note that the elsif clause of
this statement is spelled strangely, missing the second
"e" that it seems it should have. Perl can be quirky.
A related variation of the if statement is the
unless statement. This statement merely tests if the
given condition is not true:
unless (bank is open)
{ go to grocery;
go to bank }
else
{ go to bank;
go to grocery }
In this logic, if the bank is not open then we go shopping
first; otherwise the bank is open and we go to the bank first.
The unless statement can sometimes be confusing to work
through mentally, though it might help to think of it as
meaning "if the condition is not true". In every
other way unless behaves like the if statement,
and can take additional elsif and/or else clauses.
while, for, and foreach loops
"Lather, rinse, repeat" -- the insightful instructions
on the label of shampoo bottles. Yet, this bit of cleansing
wisdom sheds light on one of the most fundamental techniques
in Perl programming -- the loop. In fact, we can code the
shampoo mantra using Perl's while loop:
while (hairISgreasy)
{ lather;
rinse }
The shampoo loop starts with a conditional test: is the hair
greasy? A statement block follows this test, and this block
is executed if the condition is true. Thus, if the hair is
greasy, lather and rinse. When the statement block is completed,
the while loop control returns to the test at the top
of the loop. Is the hair greasy? If yes, the loop iterates
again, once more lathering and rinsing. This loop will iterate
ad infinitum until the while condition evaluates to false.
If, on the third iteration, the hair is no longer greasy, the
loop ends -- the statement block is not executed and program
flow drops to the next statement after the while loop's
statement block. If the while condition is false the
first time the loop is evaluated, the statement block is never
executed.
The for loop is similar in nature to the while
loop but tends to be used when counting is important. A basic
example would be a for loop which counts from 1 to 10:
for ($j=1; $j<=10; $j++)
{ print "$j\n" }
The for statement takes a three-part control:. First,
$j=1 sets the counting variable for this loop, $j, to a value
of 1. You can use any variable name you wish, but $i and $j
are historically traditional loop counters. The second part
of the for loop's control is the conditional -- in this
case, is $j less-than or equal to the value 10? The third part
of the control advances the counter. Here we use the common
autoincrement operator which simply adds 1 to the current
value of $j.
The first time through the loop, $j contains 1, and thus 1
is output by the print function. The second time
through the loop $j is incremented to 2, is compared against
10, and again is output by the print function. This
process simply repeats until $j increments to 11, which of
course is greater than 10. At that point the loop exits and
Perl passes over the statement block and moves onto the next
statement in the program.
When dealing with lists, the foreach loop provides a
simple way to iterate through each item in the list. Recall
our grocery list from earlier, @shopping. Suppose you wanted
to work with each item in @shopping:
foreach $shopping_item (@shopping)
{ do something with $shopping_item }
This foreach loop does not take any conditional. Rather,
it iterates for each item in @shopping. In each iteration, the
variable $shopping_item contains the next value in @shopping.
Thus, the first time through the loop $shopping_item is
"milk"; the second time through $shopping_item is
"bread", and so on. Within the statement block of
the foreach loop you can modify the value of
$shopping_item, if need be, without affecting the original value
in @shopping.
Perl Functions
The Perl You Need to Know
Conclusion
|