Perl's basic control flow is straightforward. Program execution starts at the beginning (the first line of the file executed) and continues to the end:
Perl's control flow directives change the order of execution--what happens next in the program--depending on the values of their expressions.
The if
directive performs the associated action only when its conditional expression evaluates to a true value:
This postfix form is useful for simple expressions. A block form groups multiple expressions into a single unit:
While the block form requires parentheses around its condition, the postfix form does not.
The conditional expression may consist of multiple subexpressions, as long as it evaluates to a single top-level expression:
In the postfix form, adding parentheses can clarify the intent of the code at the expense of visual cleanliness:
The unless
directive is a negated form of if
. Perl will perform the action when the conditional expression evaluates to false:
Like if
, unless
also has a block form, though many programmers avoid it, as it rapidly becomes difficult to read with complex conditionals:
unless
works very well for postfix conditionals, especially parameter validation in functions (postfix_parameter_validation):
The block forms of if
and unless
both work with the else
directive, which provides code to run when the conditional expression does not evaluate to true (for if
) or false (for unless
):
else
blocks allow you to rewrite if
and unless
conditionals in terms of each other:
However, the implied double negative of using unless
with an else
block can be confusing. This example may be the only place you ever see it.
Just as Perl provides both if
and unless
to allow you to phrase your conditionals in the most readable way, you can choose between positive and negative conditional operators:
... though the double negative implied by the presence of the else
block suggests inverting the conditional.
One or more elsif
directives may follow an if
block form and may precede any single else
:
An unless
chain may also use an elsif
blockGood luck deciphering that!. There is no elseunless
.
Writing else if
is a syntax errorLarry prefers elsif
for aesthetic reasons, as well the prior art of the Ada programming language.:
The ternary conditional operator evaluates a conditional expression and produces one of two alternatives:
The conditional expression precedes the question mark character (?
) and the colon character (:
) separates the alternatives. The alternatives are expressions of arbitrary complexity--including other ternary conditional expressions.
Perl exhibits short-circuiting behavior when it encounters complex conditional expressions. When Perl can determine that a complex expression would succeed or fail as a whole without evaluating every subexpression, it will not evaluate subsequent subexpressions. This is most obvious with an example:
The return value of ok()
(testing) is the boolean value obtained by evaluating the first argument, so this code prints:
When the first subexpression--the first call to ok
--evaluates to a true value, Perl must evaluate the second subexpression. If the first subexpression had evaluated to a false value, there would be no need to check subsequent subexpressions, as the entire expression could not succeed:
This example prints:
Even though the second subexpression would obviously succeed, Perl never evaluates it. The same short-circuiting behavior is evident for logical-or operations:
This example prints:
With the success of the first subexpression, Perl can avoid evaluating the second subexpression. If the first subexpression were false, the result of evaluating the second subexpression would dictate the result of evaluating the entire expression.
Besides allowing you to avoid potentially expensive computations, short circuiting can help you to avoid errors and warnings, as in the case where using an undefined value might raise a warning:
The conditional directives--if
, unless
, and the ternary conditional operator--all evaluate an expression in boolean context (context_philosophy). As comparison operators such as eq
, ==
, ne
, and !=
all produce boolean results when evaluated, Perl coerces the results of other expressions--including variables and values--into boolean forms.
Perl 5 has no single true value, nor a single false value. Any number which evaluates to 0 is false. This includes 0
, 0.0
, 0e0
, 0x0
, and so on. The empty string (''
) and '0'
evaluate to a false value, but the strings '0.0'
, '0e0'
, and so on do not. The idiom '0 but true'
evaluates to 0 in numeric context but true in boolean context, thanks to its string contents.
Both the empty list and undef
evaluate to a false value. Empty arrays and hashes return the number 0 in scalar context, so they evaluate to a false value in boolean context. An array which contains a single element--even undef
--evaluates to true in boolean context. A hash which contains any elements--even a key and a value of undef
--evaluates to a true value in boolean context.
Perl provides several directives for looping and iteration. The foreach-style loop evaluates an expression which produces a list and executes a statement or block until it has consumed that list:
This example uses the range operator to produce a list of integers from one to ten inclusive. The foreach
directive loops over them, setting the topic variable $_
(default_scalar_variable) to each in turn. Perl executes the block for each integer and prints the squares of the integers.
Like if
and unless
, this loop has a postfix form:
A for
loop may use a named variable instead of the topic:
When a for
loop uses an iterator variable, the variable scope is within the loop. Perl will set this lexical to the value of each item in the iteration. Perl will not modify the topic variable ($_
). If you have declared a lexical $i
in an outer scope, its value will persist outside the loop:
This localization occurs even if you do not redeclare the iteration variable as a lexical... but do declare your iteration variables as lexicals to reduce their scope.:
The for
loop aliases the iterator variable to the values in the iteration such that any modifications to the value of the iterator modifies the iterated value in place:
This aliasing also works with the block style for
loop:
... as well as iteration with the topic variable:
You cannot use aliasing to modify constant values, however:
Instead Perl will produce an exception about modification of read-only values.
You may occasionally see the use of for
with a single scalar variable to alias $_
to the variable:
Iterator scoping with the topic variable provides one common source of confusion. Consider a function topic_mangler()
which modifies $_
on purpose. If code iterating over a list called topic_mangler()
without protecting $_
, debugging fun would ensue:
If you must use $_
rather than a named variable, make the topic variable lexical with my $_
:
Using a named iteration variable also prevents undesired aliasing behavior through $_
.
The C-style for loop requires you to manage the conditions of iteration:
You must explicitly assign to an iteration variable in the looping construct, as this loop performs neither aliasing nor assignment to the topic variable. While any variable declared in the loop construct is scoped to the lexical block of the loop, there is no lexicalization of a variable declared outside of the loop construct:
The looping construct may have three subexpressions. The first subexpression--the initialization section--executes only once, before the loop body executes. Perl evaluates the second subexpression--the conditional comparison--before each iteration of the loop body. When this evaluates to a true value, iteration proceeds. When it evaluates to a false value, iteration stops. The final subexpression executes after each iteration of the loop body.
Note the lack of a semicolon after the final subexpression as well as the use of the comma operator and low-precedence and
; this syntax is surprisingly finicky. When possible, prefer the foreach
-style loop to the for
loop.
All three subexpressions are optional. An infinite for
loop might be:
A while loop continues until the loop conditional expression evaluates to a boolean false value. An idiomatic infinite loop is:
Unlike the iteration foreach
-style loop, the while
loop's condition has no side effects by itself. That is, if @values
has one or more elements, this code is also an infinite loop:
To prevent such an infinite while
loop, use a destructive update of the @values
array by modifying the array with each loop iteration:
Modifying @values
inside of the while
condition check also works, but it has some subtleties related to the truthiness of each value.
This loop will exit as soon as it reaches an element that evaluates to a false value, not necessarily when it has exhausted the array. That may be the desired behavior, but is often surprising to novices.
The until loop reverses the sense of the test of the while
loop. Iteration continues while the loop conditional expression evaluates to a false value:
The canonical use of the while
loop is to iterate over input from a filehandle:
Perl 5 interprets this while
loop as if you had written:
Without the implicit defined
, any line read from the filehandle which evaluated to a false value in a scalar context--a blank line or a line which contained only the character 0
--would end the loop. The readline
(<>
) operator returns an undefined value only when it has reached the end of the file.
Both while
and until
have postfix forms, such as the infinite loop 1 while 1;
. Any single expression is suitable for a postfix while
or until
, including the classic "Hello, world!" example from 8-bit computers of the early 1980s:
Infinite loops are more useful than they seem, especially for event loops in GUI programs, program interpreters, or network servers:
Use a do
block to group several expressions into a single unit:
A do
block parses as a single expression which may contain several expressions. Unlike the while
loop's block form, the do
block with a postfix while
or until
will execute its body at least once. This construct is less common than the other loop forms, but no less powerful.
You may nest loops within other loops:
When you do so, declare named iteration variables! The potential for confusion with the topic variable and its scope is too great otherwise.
A common mistake with nesting foreach
and while
loops is that it is easy to exhaust a filehandle with a while
loop:
Opening the filehandle outside of the for
loop leaves the file position unchanged between each iteration of the for
loop. On its second iteration, the while
loop will have nothing to read and will not execute. To solve this problem, re-open the file inside the for
loop (simple to understand, but not always a good use of system resources), slurp the entire file into memory (which may not work if the file is large), or seek
the filehandle back to the beginning of the file for each iteration (an often overlooked option):
Sometimes you need to break out of a loop before you have exhausted the iteration conditions. Perl 5's standard control mechanisms--exceptions and return
--work, but you may also use loop control statements.
The next statement restarts the loop at its next iteration. Use it when you've done all you need to in the current iteration. To loop over lines in a file but skip everything that starts with the comment character #
, write:
The last statement ends the loop immediately. To finish processing a file once you've seen the ending token, write:
The redo statement restarts the current iteration without evaluating the conditional again. This can be useful in those few cases where you want to modify the line you've read in place, then start processing over from the beginning without clobbering it with another line. To implement a silly file parser that joins lines which end with a backslash:
Using loop control statements in nested loops can be confusing. If you cannot avoid nested loops--by extracting inner loops into named functions--use a loop label to clarify:
The continue
construct behaves like the third subexpression of a for
loop; Perl executes its block before subsequent iterations of a loop, whether due to normal loop repetition or premature re-iteration from next
The Perl equivalent to C's continue
is next
.. You may use it with a while
, until
, when
, or for
loop. Examples of continue
are rare, but it's useful any time you want to guarantee that something occurs with every iteration of the loop regardless of how that iteration ends:
Be aware that a continue
block does not execute when control flow leaves a loop due to last
or redo
.
The given
construct is a feature new to Perl 5.10. It assigns the value of an expression to the topic variable and introduces a block:
Unlike for
, it does not iterate over an aggregate. It evaluates its expression in scalar context, and always assigns to the topic variable:
given
also lexicalizes the topic variable:
given
is most useful when combined with when
(smart_match). given
topicalizes a value within a block so that multiple when
statements can match the topic against expressions using smart-match semantics. To write the Rock, Paper, Scissors game:
Perl executes the default
rule when none of the other conditions match.
A tailcall occurs when the last expression within a function is a call to another function--the outer function's return value is the inner function's return value:
Returning from greet_person()
directly to the caller of log_and_greet_person()
is more efficient than returning to log_and_greet_person()
and immediately from log_and_greet_person()
. Returning directly from greet_person()
to the caller of log_and_greet_person()
is a tailcall optimization.
Heavily recursive code (recursion), especially mutually recursive code, can consume a lot of memory. Tailcalls reduce the memory needed for internal bookkeeping of control flow and can make expensive algorithms tractable. Unfortunately, Perl 5 does not automatically perform this optimization; you have to do it yourself when it's necessary.
The builtin goto
operator has a form which calls a function as if the current function were never called, essentially erasing the bookkeeping for the new function call. The ugly syntax confuses people who've heard "Never use goto
", but it works:
This example has two important features. First, goto &function_name
or goto &$function_reference
requires the use of the function sigil (&
) so that the parser knows to perform a tailcall instead of jumping to a label. Second, this form of function call passes the contents of @_
implicitly to the called function. You may modify @_
to change the passed arguments.
This technique is relatively rare; it's most useful when you want to hijack control flow to get out of the way of other functions inspecting caller
(such as when you're implementing special logging or some sort of debugging feature), or when using an algorithm which requires a lot of recursion.
Hey! The above document had some coding errors, which are explained below:
- Around line 3:
-
A non-empty Z<>
- Around line 201:
-
Deleting unknown formatting code N<>
- Around line 204:
-
Deleting unknown formatting code N<>
- Around line 261:
-
A non-empty Z<>
- Around line 385:
-
A non-empty Z<>
- Around line 457:
-
Deleting unknown formatting code N<>
- Around line 991:
-
Deleting unknown formatting code N<>
- Around line 1019:
-
A non-empty Z<>
- Around line 1134:
-
A non-empty Z<>