Troubleshooters.Com and Code Corner Present

Steve Litt's Perls of Wisdom:
Looping and Branching in Perl
(With Snippets)

Copyright (C) 1998 by Steve Litt


Contents

Branching

Check this out:

if ($president eq "Bill Clinton")
   {
   print "$president: After 1992.\n";
   }
elsif($president eq "George Bush")
   {
   print "$president: 1989 through 1992.\n";
   }
else
   {
   print "$president: Before 1989\n";
   }

Note the following:

The unless Keyword

If you're like me, you think this is ugly:

if(!($president eq "Bill Clinton"))

You'll be glad to know you can do this:

unless($president eq "Bill Clinton")

However, keep in mind that C/C++/Java/Delphi programmers will pause and scratch their head because they're not used to the concept of a negative if.

Other Constructs

$president eq "Bill Clinton" or print "Former president\n";

This means the same as

if(!($president eq "Bill Clinton"))
 {print "Former president\n";}

Most Perl programmers also work in other languages, and the former construct will give them vertigo. The saved if, parentheses, exclamation, and curly brackets aren't worth it. The one exception is the standard file open construct:

open(CONFIG, "c:\\config.sys") or die "Could not open config.sys.";

Now here's one guaranteed to get C++ programmers queazy:

print "Current president\n" if $president eq "Bill Clinton";

Note that now you needn't put the conditional expression in parentheses. This means the same as:

if($president eq "Bill Clinton)
  {print "Current president\n"}

When everyone uses Perl, the former construct will be readable. Until then, I'd suggest using the good old "if first" construct.

There are other constructs which are so way out I won't even discuss them. Please just remember the person reading your code probably works mainly in C++ or Java.

Comparators

The following simple comparators work in if statements, loops, etc. Note there are tons more comparators, but they can be synthesized with those below. Note also that any comparison can include a regular expression, which has its own page in this website.

Comparison

Numeric

Non-Numeric

Equality
==
eq
Non equality
!=
ne
Greater than
>
gt
Greater or equal
>=
ge
Less than
<
lt
Less or equal
<=
le


Looping

Top Testers

while(ENABLER_EXPRESSION)
  {ACTIONS}
until(DISABLER_EXPRESSION)
  {ACTIONS}

Note:

Perl also has the handy for() statement:

for ($i = 1; $i < 10; $i++)
 {
 ACTIONS;
 }

Note:

Bottom Testers

do
  {ACTIONS}
while (ENABLER_EXPRESSION);
do
  {ACTIONS}
until (DISABLER_EXPRESSION);

Note:


Looping Through a File

This opens autoexec.bat for input, autoexec.rem for output, and copies only the lines that aren't remmed out. Note that this has only one line of the file in memory at a time, so it's useful for extremely large files.

open(INPUT,  "autoexec.bat");
open(OUTPUT, ">autoexec.rem");   # The > means open for write, 
                                 #  over original if existed.

while (<INPUT>)
  {
  my($line) = $_;  #preserve $_, the line just read, nomatter what
  chomp $line;     #blow off trailing newline

  unless($line =~ /^\s*rem/i)    #see regular expressions for explanation
    {
    print OUTPUT "$line\n";      #write the non-remmed autoexec command
    }
  }
close(INPUT);
close(OUTPUT);

Looping Through a List

There's a special construct, called foreach, for looping through a list. It automatically assigns the next element of the list to a scaler. The construct is like this:

foreach SCALAR (LIST)
 {ACTIONS} 

Here's a file dup detector that uses this construct. Note that since the entire list is in memory, this isn't suitable for files that may attain a huge size.

my(@allLines);                   #declare list to hold all file lines
my($line);                       #declare local scalar for each line
my($dupCount);
my($lastLine);                   #declare scaler to hold previous line
@allLines = sort(<INPUT_FILE>);  #put all lines of input file into list
                                 # sort list for duplicate detection
$lastLine="~~~ ~~";              #no break first time
$dupCount = 0;
foreach $line (@allLines)        #one by one, put next element into scalar
  {
  chomp($line);                  #blow off trailing newline
  if($line eq $lastLine)         #if duplicate of previous line
    {
    print "$lastLine\n";
    $dupCount++;
    }
  $lastLine = $line;
  }
print "-----------------\n";
print "$dupCount Duplicates.\n";


 [ Troubleshooters.com | Code Corner | Email Steve Litt ]

Copyright (C)1998 by Steve Litt -- Legal