More interesting possiblities arise when we introduce control
structures and looping. Perl supports lots of different kinds of
control structures which tend to be like those in C, but are very
similar to Pascal, too. Here we discuss a few of them.
To go through each line of an array or other list-like structure (such
as lines in a file) Perl uses the foreach structure. This has the form
foreach $morsel (@food) # Visit each item in turn
# and call it $morsel
{
print "$morsel\n"; # Print the item
print "Yum yum\n"; # That was nice
}
The actions to be performed each time are enclosed in a block of curly
braces. The first time through the block $morsel is assigned the value
of the first item in the array @food. Next time it is assigned the
value of the second item, and so until the end. If @food is empty to
start with then the block of statements is never executed.
The next few structures rely on a test being true or false. In Perl
any non-zero number and non-empty string is counted as true. The
number zero, zero by itself in a string, and the empty string are
counted as false. Here are some tests on numbers and strings.
$a == $b # Is $a numerically equal to $b?
# Beware: Don't use the = operator.
$a != $b # Is $a numerically unequal to $b?
$a eq $b # Is $a string-equal to $b?
$a ne $b # Is $a string-unequal to $b?
You can also use logical and, or and not:
($a && $b) # Is $a and $b true?
($a || $b) # Is either $a or $b true?
!($a) # is $a false?
Perl has a for structure that mimics that of C. It has the form
for (initialise; test; inc)
{
first_action;
second_action;
etc
}
First of all the statement initialise is executed. Then while test is
true the block of actions is executed. After each time the block is
executed inc takes place. Here is an example for loop to print out the
numbers 0 to 9.
for ($i = 0; $i < 10; ++$i) # Start with $i = 1
# Do it while $i < 10
# Increment $i before repeating
{
print "$i\n";
}
Here is a program that reads some input from the keyboard and won't
continue until it is the correct password
#!/usr/local/bin/perl
print "Password? "; # Ask for input
$a = ; # Get input
chop $a; # Remove the newline at end
while ($a ne "fred") # While input is wrong...
{
print "sorry. Again? "; # Ask again
$a = ; # Get input again
chop $a; # Chop off newline again
}
The curly-braced block of code is executed while the input does not
equal the password. The while structure should be fairly clear, but
this is the opportunity to notice several things. First, we can we
read from the standard input (the keyboard) without opening the file
first. Second, when the password is entered $a is given that value
including the newline character at the end. The chop function removes
the last character of a string which in this case is the newline.
To test the opposite thing we can use the until statement in just the
same way. This executes the block repeatedly until the expression is
true, not while it is true.
Another useful technique is putting the while or until check at the
end of the statement block rather than at the beginning. This will
require the presence of the do operator to mark the beginning of the
block and the test at the end. If we forgo the sorry. Again message in
the above password program then it could be written like this.
#!/usr/local/bin/perl
do
{
"Password? "; # Ask for input
$a = ; # Get input
chop $a; # Chop off newline
}
while ($a ne "fred") # Redo while wrong input
Modify the program from the previous exercise so that each line of the
file is read in one by one and is output with a line number at the
beginning. You should get something like:
1 root:oYpYXm/qRO6N2:0:0:Super-User:/:/bin/csh
2 sysadm:*:0:0:System V Administration:/usr/admin:/bin/sh
3 diag:*:0:996:Hardware Diagnostics:/usr/diags:/bin/csh
etc
You may find it useful to use the structure
while ($line = )
{
...
}
When you have done this see if you can alter it so that line numbers
are printed as 001, 002, ..., 009, 010, 011, 012, etc. To do this you
should only need to change one line by inserting an extra four
characters. Perl's clever like that.