Getting Started
Introduction
Perl IDEs
History
Advice
Tools
Mini-Tutorial
Tutorial
Code Snippets

Resources
Top Sites
More Tutorials
Books
Magazines
Articles
NewsLetters
Mailing Lists
NewsGroups
Forums
User Groups
Talk Shows
Blogs
Clothing

GBIC >> Perl >> Information Center Tutorials >> Flow Control

Perl Information Center Tutorials - Flow Control
These tutorials were written to help you get a quick, but thorough, understanding of Perl - the scope of the language as well as it's specific capabilities.

Beginners Built-In Functions     Advanced CGI Applications

Flow Control
Perl contains several mechanisms to repeat blocks of code (looping) or to execute a block of code depending on the results of an expression. It also provides methods of jumping to a labeled block of code.

Blocks
One or more statements can be enclosed in curly-brackets, { }, to create what Perl calls a block of code, as in the following example:

blocklabel:  {             # the blocklabel is optional
       $a = 5;
       @x = (1,2,3);
     }

A block can be given an optional label. Perl provides various functions, including a goto function which uses the labels.

BEGIN/END Blocks
Code blocks labeled BEGIN, CHECK, INIT and END are recognized by the Perl interpreter. These blocks are executed at the beginning and at the end of a Perl program.

A BEGIN code block is executed as soon as possible, whereas the END code block is executed after Perl has finished running the program.

There are several nuances in the use of these named blocks, so please see perldoc for additional information on their use.

Expressions
An expression is simply Perl code which resolves to a value. Expressions are typically contained within parentheses. Parentheses are also used to contain lists, where each member of the list is a separate expression.

     (5)              # parentheses (list) with a single, simple expression
     (5,"dog",2.5)    # parentheses with 3 simple expressions
     ($a+2)           # list with a single expression
     (sin($b)+3, 7)   # list with two expressions
     $x=3             # successful Perl statements return a value of 0

Conditional Execution
Perl supports several flow-control operators, similar to other languages such as C. These operators direct Perl to complete a block of code depending on the true/false value of an expression.

The following examples show how the if, unless, while, and until conditional operators. The earlier definitions of expressions and blocks apply to these examples.

Note that the block of code is executed only one time when these operators are used.

     if (expression) {..statements..}
     unless (expression) {..statements..}   #same as   if (!expression)
     while (expression) {..statements..}
     until (expression) {..statements..}

Perl syntax also supports reversing the expressions as follows:

     {..statements..} if (expression) 
     {..statements..} unless (expression) 
     {..statements..} while (expression) 
     {..statements..} until (expression) 

Perl also supports a special syntax for the if operator, allowing multiple expressions to be tested as shown in the following example.

     if (expression) {..statements..}
     elsif (expression) {..statements..}
     elsif (expression) {..statements..}
     else {..statements..}

Both the elsif and else lines are optional. When used, any number of elsif statements may be used.

Perl also supports another variation on the if operator, the conditional operator which is written as ?:, as in the following example.

     (expression) ? (..true statements..) : (..false statements..)
     (a$) ? (print 'true') : (print 'false')

Conditional Looping
Perl also provides two means of repeating a block of statements, the for and foreach operators.

The for operator explicitly numbers how many times a block of code is repeated, as in the following examples:

     for ( initvalue; test; increment) {..statements..}   # general format
     for ($i=0; $i <= $max; $i++) {..statements..}        # specific example

The Perl foreach operator repeats a block of code for each value in a list, as in the following example.

     foreach $var (list) {..statements..}     # list members put in $var
     foreach $b (1,2,3) { print $b;}
     foreach $b (@myarray) { print $b;}

     foreach (list) {..statements..}          # list members put in $_
     foreach (1,2,3) { print; }               # $_ is printed
     foreach (@myarray) { print; }            # $_ is printed

Continue Block
In Perl a block of code may be followed by a second block, with the word 'continue' in between the two blocks. The second block will be executed following the first block.

     { ... }  continue  { ... }

When the first block of code is associate with a while or foreach flow control statement, the continue block of code will alway be executed before the conditional is about to be evaluated again.

     while (EXPR) { 
          do something:
     } continue {
          do something else;
     }

See the next paragraph for how a continue block is executed when a redo/next/last is used in a loop.

Loop Redirection
Perl provides three methods for changing the order of executing statements within a loop - redo, next, and last.

  • redo - restarts loop block without evaluating the conditional again (continue block is not executed)
  • next - starts the next iteration of the loop (continue block is executed)
  • last - exits current loop immediately (continue block is not executed)

Here are examples of each.

     while (<INFILE>) {
         next if /^#/;       # ignore if line starts with #
         print;              # print the line if not a comment
         last if /^stop/;    # stop looping if line starts with 'stop'
         redo if /twice/     # print line twice if starts with 'twice'
     }
     continue { print "..reading" }  # executed on next/redo, not on last

     while (EXPR) {
 	# redo always comes here
 	do_something;
     } continue {
 	# next always comes here
 	do_something_else;
 	# then back the top to re-check EXPR
     }
     ### last always comes here

If you have any questions or corrections, please let me know.