Perl Introduction

Perl Introduction

Perl is a general purpose programming language, it is intended to be a practical language (easy to use), it offers multiple programming paradigms (procedural, object-oriented and functional), it also has a vast collection of third-party modules.

Perl is a interpreted language (scripting language) which means it does not have to be compiled before running it, although this means that it is not as fast as C or Java it is very quick in that you can change the code and run it immediately.

Perl offers the following

Perl was originally named 'Pearl' after the Parable of the Pearl from the Gospel of Matthew, but the creator Larry Wall wanted to give it a short name, however before Perl release it was discovered that there was already a programming languages called PEARL so the name got changed to Perl.

Perl is occasionally referenced as 'Practical Extraction and Reporting Language' but it did not derive its name from this.

Perl was first release in 1987 to the comp.sources.misc newsgroup, Perl 2 was released in 1988, Perl 3 1989, Perl 4.0 in 1993 and Perl 5 was released in 1994. Perl 6 (a complete rewrite) is in current development.

The Camel associated with Perl was first introduced in 1991 with the release of O'Reilly's media 'Perl Programming' book, the picture of a Camel was on the front of the book.

The official site for Perl is www.perl.org from this site you can obtain the source code, documentation and lots of additional Perl modules.

Getting Started

Make sure that you have Perl on your system, if not grab a copy for the O/S that you have

Unix www.perl.org
Windows www.activestate.com

Running a Perl program

In the Unix environment there are two ways to run a perl program first by supplying your perl source code as one of the arguments to the perl executable or by placing a line of code which tells the shell where to locate the perl interpreter (this must be the first line of code).

Using perl source code as an argument to the perl executable perl hello_world.pl
Run the source without specifying the perl executable

hello_world.pl

Note: the below line must be the first line of code, you can find the location of perl by using the which command, also the perl program must have executable privileges

#!/usr/local/bin/perl

Obtain Perl version perl -v

In the windows world I have download a IDE environment (GUI) which allows me to edit the perl source code as well as run it, just make sure that the IE points to the Activestate perl executable

Executing in GUI http://open-perl-ide.sourceforge.net/
Executing in DOS prompt perl hello_world.pl
Obtain Perl version perl -v

Sample Script

The first line tells the shell where to locate the interpreter (in this case the perl interpreter), the second line is a simple print statement.

Sample Code

#!/usr/local/bin/perl
print "Hello World!\n";

A statement is one task for the perl interpreter to perform, a perl program can be thought of as a collection of statements performed one at a time. The statement ends with a semi-colon as with the code above the print statement ends with a semi-colon.

The perl interpreter will ignore any whitespace unless it is in either single of double quotes.

You can use any editor (vi, emacs, notepad, IDE) to change perl source code, becareful if developing on windows and copying the code to a unix server, occasionally you end up with the DOS carriage return (^M) statements at the end of the code, use the 'Dos2Unix' command to remove these.

Perl User interaction

Perl has 3 ways to communicate with the user.

The default and other common options that they can use are

STDIN

keyboard (default)
file to obtain data from

STDOUT monitor (default)
logfile
STDERR monitor (default)
console port
error logfile

Basic Operators and Control Flow

Scalar Variable

The definition of a scalar variable is that it stores one item (line of input, piece of text, number), the name of a scalar variable starts with a $ sign and must be followed by at least one letter

Good Names $x
$var
$total_value
$x1234
$this_is_a_very_long_name_but_legal
Bad Names $              - there must be at least one letter in the name
$47x          - the second character must be a letter
$var!         - you cannot have ! in a variable
$new.var   - you cannot have a . in a variable

Perl variables are case sensitive

All different variables $var
$Var
$VAR

You assign values to variable but using the assignment operator =

Assigning values

$var = "Hello World!";

$total_salary = 13000;

Note: do not forget the semi-colon at the nd to terminate the statement

Performing Arithmetic

Perl uses the basic arithmetic operators

Arithmetic operators +     - addition
-     - subtraction
/     - divison
*     - Multiplication
Examples $var = 7 + 5;
$var = 30 - 8;
$var = 20 - 5 * 10;

$var = 16;
$var_total = $var - 6 + 10;

Conditional Statements

Perl uses conditional statements if, while and until

IF Statement

if ($number) { print "The number is not zero"; }

if ($number == 21 ) { print "The number is 21 "; }

 

IF-ELSE statement if ($number1 == $number2) {
       print "The two numbers are equal";
}
else {
       print "The two numbers are not equal";
}
IF-ELSIF-ELSE statement

if ($number1 == $number2) {
       print "Number1 is equal to number2";
}
elsif ($number1 == $number3) {
       print "Number1 is equal to number3";
}
elsif ($number1 == $number4) {
       print "Number1 is equal to number4";
}
else {
       print "Number1 does not match any number ";
}

While Statement

$number = 1;

while ($number != 5) {
    print ( "The number is still not 5\n");
    $number = $number + 1;
}

Note: There is a possibility that the while loop will not run if the condition has already been meet.

Until Statement

$number = 5;

until ($number == 5) {
   print "Number is not 5 yet!\n";
   $number = $number +1 ;
}

Note: in other languages until loop always runs at least once but perl is different, if the conditional statement has already been meet then the until loop will not run as shown above

See More Control Structures for information on single-line conditional statements, loops and the goto statement.

Understanding Scalar Values

A Scalar Value is one unit of data, the data can either by a number or a chunk of text. All scalar variable have an initial value of the null string if not assigned, this means that you do not need to define.

In scalar values, a value that was assigned as a string can be used as a integer whenever it makes sense to do so and vice versa.

Scalar Values
Integer

Can contain one or more digits, optionally proceeded by either a plus or minus sign and optionally containing underscores. There is a limit of how many digits can be contained in the number, this depends on the type of machine you use.

To use octal number you start the number with a 0 (zero)

Floating-Point

A floating point number consists of the following

  • An optional minus sign (-)
  • A sequence of digits, optionally containing a decimal point
  • An optional exponent

The exponent represent the value by which to multiply or divide the scalar value by a power of ten. the exponent e+01 means multiply by ten, e+02 means multiply by 100 and e+03 means multiply by 1000, etc. The exponent e-01 means divide by ten, e-02 means divide by 100 and so on.

Remember that round-off will occur when perl meets it maximum limit, this depend on what machine you use.

Octal and Hexadecimal

Perl also enables you to use two other notations to represent integer scalar values

  • Base 8 (octal)
  • Base 16 (hexadecimal)
Character Strings

A character string is a sequence of one or more letters, digits, spaces or special characters. When you assign a string variable you can either use double quotes (variable substitution) or single quotes (no substitution).

Variable substitution means that when Perl sees a variable ( starts with a dollar sign($) ) inside the double quotes it knows that this is a variable and substitutes it for the variable's value.

There are lots of escapes sequences for character strings and need to be in double quotes to work, see Perl Cheat sheet for more details

Scalar Value Examples
Integer

$salary = 10000;
$pay_reduction = -100;

Floating-Point

$mars_bar = 0.50;
$breakages = -1.50;
$bonus = .1;

$a_large_number = 1.2e+05;          # remember that e+05 means multiply by 100000
$a_tiny_number = 1.2e-05;           # remember that e-05 means divide by 100000

Octal and Hexadecimal $result = 047;                      # this assign octal 47 or decimal 39 ( notice the leading 0 (zero) )
$result = 0x1f;                     # this assign hexadecimal 1F or decimal 31 ( notice the leading 0x)
Character Strings

$string = "Hello World";

## Substitution (double and single quotes)
$string = "You have $balance in your bank";   # using double quotes $balance will be substituted with the value of $balance
$string = 'You have $balance in your bank';   # will not substitute $balance because single quotes means take literary        

## Using escape sequences
$string = "Hello World!\n";         # notice the new line feed escape sequence
$string = "Hello World!\a";         # beep when you print this
$string = "\uhello World!\n";       # \u forces the h to become upper case

## Using a string as a integer
$string = "43";
$number = 57;
$result = $string + $number;        # the value of string is converted into a number and then added

More Perl Operators

There are many more operators in Perl besides the more basic ones.

Perl Operators
Exponentation Exponentational provides away to multiply a number to itself repeatedly
Remainder Retrieves the remainder resulting from division of one integer by another
Unary Negation Is a character in front of a single value, it is equivalent to multiplying the value by -1
Integer Comparison There are many comparison operators - see Perl Cheat Sheet, becareful when comparing floating-point numbers as rounding up may make numbers different
String Comparison There are many comparison operators - see Perl Cheat Sheet
Logical

Can used to to check for multiply conditions like a if-else statement, Short-circuit evaluation means that in some circumstances if a part of the evaulation forces the outcome of the statement to be true or false regardless if the other part outcome

   if ( $age == 5 || $age == 10 )   ## the second condition will not be checked of $age equals 5, the outcome will be true anyway

Bit-Manipulation You can manipulate the binary digits (or bits) of an integer there are many bit-manipulation operators - see Perl Cheat Sheet
Assignment Associates or assigns a value to a variable, you can use the operator more than once in a single statement
Autoincrement and autodecrement The autoincrement and autodecrement is a third way to increment/decrement variables by 1, you can also increment/decrement strings.
String concatenation There are a number of operators that can effect strings - see Perl cheat sheet
Repetition Make multiple copies of a string and joins the copies together.
Comma Guarantees that a particular part of an expression is evaluated first
Conditional This is know as a tenary operator in other languages and is based on a if-else statement
Perl Operators Examples
Exponentation

$x = 2 ** 4;          # take four copies of two and multiply them (2 * 2 * 2 * 2 = 16)
$y = 3 ** 5;          # 3 * 3 * 3 * 3 * 3 = 243;

$ x = 2 ** -5;        # this is the fraction 1/32

Remainder

$x = 25 % 4;          # 25 divided by 4 yields 6 with a remainder of 1, so $x = 1
$x = 24 % 7;          # 24 divided by 7 yields 3 with a remainder 0f 3, so $x = 3

Unary Negation $x = - 5;             # $x = -5;
$x = - $y ;           # $x = $y * -1;
Integer Comparison

if ( $a == $b )  { .... }
if ( $a < $b )   { .... }
if ( $a > $b )   { .... }
if ( $a <= $b )  { .... }
if ( $a >= $b )  { .... }
if ( $a != $b )  { .... }
if ( $a <=> $b ) { .... }

String Comparison if ( $stringA eq $stringB )    { .... }
if ( $stringA lt $stringB )    { .... }
if ( $stringA gt $stringB )    { .... }
if ( $stringA le $stringB )    { .... }
if ( $stringA ge $stringB )    { .... }
if ( $stringA ne $stringB )    { .... }
if ( $stringA <cmp> $stringB ) { .... }
Logical

if ( $age > 5 && $age < 17 ) { .... }
if ( $age > 5 && $age < 17 || $person eq "teacher") { .... }

if ( ! $x ) { .... }     # true if $x is not zero and false if $x is 0;

Bit-Manipulation

$x = 124 & 99;         # 01111100 (124) & 01100011 (99) = 01100000 (96)
$x = 124 | 99;
$x = 124 ^ 99;
$x = ~99;

$result = $x >> 1;     # shift bits to the right 01100011 (99) becomes 00110001 (49)
$result = $x << 1;     # shift bits to the left 01100011 (99) becomes 11000110 (198)

Assignment $a = 5;                # assign the value 5 to the variable $a
$a += 5;               # really means $a = $a + 5
$a *= 10;              # really means $a = $a * 5
$a ^= 95;              # really means $a = $a ^ 5
Autoincrement and autodecrement $a++                   # post-increment
++$a                   # pre-increment

$a--                   # post-decrement
--$a                   # pre-decrement
String concatenation

$you_are_a = $potatoe . $head;    # this concatenation variables $potatoe, $head into one string value

$a = "Magic"
$a .= "Roundabout"                # produces "Magic Roundabout"

Repetition $strong_mint = "X" x 3;           # procedues the string "XXX"
Comma $var1 += 1, $var2 = $var1;        # the list of statements will be processed from left to right
Conditional

$result = $var == 0 ? 14 : 7;     # if $var equals 0 then $result = 14, if $var is not equal to 0 then                                   # $result = 7

Precedence

Operators are governed by a set of rules, these are called the 'rules of precedence', the precedence will determine the process statement order , highest being first, You can force the order of precedence by using brackets

Force Precedence $result = 4 * ( 5 + 3 );          # Normally the mulitplication would be processed first,
                                  # but by using brackets we force the addition to be
                                  # processed first

Pattern Matching

A pattern is a sequence of characters to be searched for in a character string. Perl patterns are normally enclosed in slash characters /def/.

There are two pattern Matching operators

Pattern Matching Operators
Pattern Match

Pattern matched - NON Zero or true returned
NO Pattern Matched - 0 or False returned

No Pattern Match NO Pattern matched - NON Zero or true returned
Pattern Matched - 0 or False returned
Pattern Matching Operators Examples
Pattern Match

$result = $var =~ /abc/;                     # true if $var has abc in the string

if ( $question =~ /right/ ) { .... }         # true if $var has abc in the string, false if abc is not in $var

No Pattern Match

$result = $var !~ /abc/;                     # true if $var does not have abc in the string

if ( $question !~ /right/ ) { .... }         # true if $var does not have abc, false if abc does appear in string $var

Pattern match operators do have a order of precedence which can be viewed from the Perl Cheat Sheet.

Special Characters

There are a number of special characters which can be used inside the patterns, which enables you to match any of a number of character strings, these are what make patterns useful.

Special Characters
. character matches any character except the newline character, the special combination of .* tries to match as much as possible.
+ character means one or more of the preceding characters
[ ] character enable you to define patterns that match one of a group of alternatives, you can also uses ranges such as [0-9] or [a-z,A-Z]
* character match zero or more occurrences of the preceding character
? character match zero or one occurrence of the preceding character
Pattern anchor there are a number of pattern anchors, match at beginning of a string (^ or \A), match at the end of a string ($ or \Z), match on word boundary (\b) and match inside a work (\B - opposite of \b)
Escape sequence if you want to include a character that is normally treated as a special character, you must precede the character with a backslash, you can use the \Q to tell perl to treat everything after as a normal character until it see's \E
Excluding you can exclude words or characters by using the ^ inside square brackets [^]
Character-Range escape sequences there are special character range escape sequences such as any digit (\d), anything other than a digit (\D), to see the full list see Perl Cheat Sheet
Specified number of occurrences you can define how any occurrences you want to match using the {<minimum>,<maximum>}
specify choice the special character | (pipe) enables you to specify two or more alternatives to choose from when matching a pattern
Portition reuse some times you want to store what has been matched, you can do this by using (), the first set will be store in \1 (used in pattern matching) or $1 (used when assigning to variables) , the second set \2 or $2 and so on.
Different delimiter you can specify a different delimiter
Special Characters Examples
. character /d.f/          # could match words like def, dif, duf
/d.*f/         # could match words like deaf, deef, def, dzzf, etc
+ character /de+f/         # could match words like def, deef, deeef, deeeef, etc
/ +/           # match words between multiple spaces
[ ] character

/d[eE]f/       # match words def or dEf
/a[456]c/      # match a followed by any digit then c such as a4c, a5c or a6c
/d[eE]+f/      # match words like def, dEf, deef, dEeF, dEEeeEef, etc

/d[a-z]f/      # match words like def, def, dzf, dsf, etc
/1[0-9]0/      / match numbers like 100, 110, 120, 150, 170, 190, etc

* character /de*f/         # match words like df, def, deef, deeef, etc
? character /de?f/         # match only the words df and def (not deef only matches one occurence)
Pattern anchors

/^hello/       # match only if line starts with hello
/hello$/       # match only if hello is at end of line

/\bdef/        # only matches when def is at the beginning of a word define, defghi
/def\b/        # only matches when def is at the end of a word abcdef

/\Bdef/        # matches abcdef (opposite of \b)
/def\B/        # matches defghi (opposite of \b)

Escape sequence /\+salary/     # will match the word +salary, the + (plus) is treated as a normal character because of the \
/\Q**++\E/     # will match **++
Excluding /d[^eE]f/      # 1st character is d, 2nd character is anything other than e or E, last character is f
Character-Range escape sequences /\d/           # match any digit
/\d+/          # match any number of digits
Specified number of occurrences /de{3}f/       # match only deeeef the {3} means three preceding e's
/de{1,3}       # match only deef, deeef and deeeef ( minimum = 1, maximum = 3 occurrences)  
specify choice /def|ghi/      # match either def or ghi
Portition reuse /(def)(ghi)/   # the first matched pattern will be store in \1 or $1, the second in \2 or $2
$result = $1;  # assign the obtained matched pattern above in $result
$result2 = $2; # assign the second obtained matched pattern above in $result2
Different delimiter !/usr/sbin!    # match /usr/sbin, here we are using the ! (bang) character as a delimiter

Pattern-Matching Options

When you specify a pattern, you can also supply options that control how the pattern is to be matched, to see the full list see the Perl Cheat Sheet

Pattern-Matching Options Examples
Match all possible patterns
(global)
@matches = "balata" =~ /.a/g;    # Matches ba, la and ta
$matches = "balata" =~ /.a/g;    # Matches the first occurrence ba
Ignore case /de/i                            # matches de, De, dE or DE
Treat string as multiple lines /^The/m                          # Match the word in multiple lines
Only evaluate once /def/o                           # Match only the first occurrence
Treat string as single line /a.*bc/s                         # Used when you multiple lines
Ignore white space in pattern /\d{2} \d{2} /x                  # ignore the spaces in the pattern so the code is                                  # interpreted as /\d{2}\d{2}/ spaces make the code easier
                                 # to read
substitution

s/abc/def/                       # substitute the first occurrence of abc with def
s/abc//                          # delete first occurrence abc
s/abc//g                         # delete all occurrences of abc (global substitution)

Note: you can use any other pattern-matching option with substitution

Translation

tr/abc/def/                      # translate all a into d, all b into e, all c into f
y/a-z/A-Z/                       # translate all characters into upper case, a=A, b=B, etc

Note: you can use y/ instead of tr/, you have several options
/c  -  Translate all characters not specified
/d  -  Delete all specified characters
/s  -  Replace multiple identical output characters with a single character

More Perl Control Structures

Single-Line Conditional Statements

Single-Line Conditional Statement print ("Hello World!\n") if ( $var == 0 );
print ("Hello World!\n") unless( $var != 0 );
print ("Hello World!\n") while ( $var-- > 0 );
print ("Hello World!\n") until ( $var-- == 0 );

die( "ERROR opening file\n") unless (open(INFILE, "employees.dat"));

Looping Control Statements

For statement

for ($count = 1; $count <= 10; $count++)
{
   print ("Count: $count");
}

## More complex for loop
for ($line = <STDN>, $count = 1; $count <= 3; $line = <STDIN>, $count++)
{
   print ($line);
}

for ( control variable initialization ; loop continuation ; increment/decrement of the control variable )

Foreach Statement

@word = qw( hello world goodbye and goodnight );

foreach $word (@word)
{
   print ("The word is $word\n");
}

## More complex foreach loop
$line = "This is a lovely day to be fishing";

foreach $word (reverse sort split(/[ ]+/, $line))
{
   print ("$word ");
}    

Do Statement

$count = 1;
do {
  $count++;
  print ("$count\n");
} while ($count < 10);

Note: the do statement will execute at least once

Last Statement

$count = 1;
while ( $count <= 10 )
{
   print ("Count: $count \n");
   last if ($count >= 5);          // break out of the while loop if $count is 5
   $count++;
}

Next statement $count = 1;
while ( $count <= 10 )
{
   next if ($count++ % 2 == 0);
   print ("Count: $count \n");
}
Redo Statement

$count = 1;
while ( $count <= 10 )
{
  redo if ($count++ % 2 == 0);   // because of this statement goes beyond 10
  print ("Count: $count \n");
}

Note: notice that the loop continues beyond the while loops condition because of the redo statement

Labeled Blocks

STOP: for ( $row = 1; $row <= 10; $row++ )
      {
         for ( $column = 1; $column <= 5; $column++ )
         {
            print ("Column : $column Row: $row\n");
            last STOP if ( $row == 5 );
         }
      }

Note: you can also use redo and next with labeled blocks

Continue block $count = 1;
while ( $count <= 10 )
{
   print ("Count: $count\n");
}
continue
{
   $count++;
}

Goto Statement

For completeness I have included the goto statement but you should never ever use this statement

Goto statement

JUMPHERE: print ("Do not use the goto statement\n");
print ("This statement is below the goto statement\n");
goto JUMPHERE;

Note: this code will result in a infinite loop, told you so never ever use goto statements

Perl Subroutines

Subroutines are used to divide your program into smaller more manageable modules. A subroutine is a separate body of code that performs a specific task Subroutines serve two purposes

Defining sub salaryCheck {
   if ( $salary > 50000)
   {
      print("You are promoted to manager\n");
   }
}
Invoking

#####################
## salaryCheck SUB ##
#####################
sub salaryCheck {
   if ( $salary > 50000)
   {
      print("You are promoted to manager and required to work 20 hours more\n");
   }
}

#####################
##      MAIN       ##
#####################
$salary = 60000;

print("Checking your salary\n");
&salaryCheck;

Note: the comments making it clear where the subroutines are, this helps any programmer when he/she has to change your code.

You use the keyword sub to define a subroutine, it does not matter where in the program you define your subroutine (I personally like to put subroutines at the top, that's just me). You use the & (ampersand) followed by the name of the subroutine to invoke a subroutine, the & tells the perl interpreter that the following name is a subroutine. You can remove the & (ampersand) when calling the subroutine only if the subroutines has been defined already ( I personally use the & (ampersand)).

remove & (ampersand) when invoking a subroutine

salaryCheck;                      ## This would fail as the subroutine has not been defined yet
                                  ## Now you know why i like putting subroutines at the top

#####################
## salaryCheck SUB ##
#####################
sub salaryCheck {
   if ( $salary > 50000)
   {
      print("You are promoted to manager and required to work 20 hours more\n");
   }
}

#####################
##      MAIN       ##
#####################
$salary = 60000;

print("Checking your salary\n");
salaryCheck;                       ## LOOK no & (ampersand)

Note: you can only obmit the & (ampersand) if the subroutines are defined before calling them

Returning a value from a Subroutine

The last value of the last expression evaluated by the subroutine is automatically considered to be the subroutine's return value

Subroutines return value ####################
## getNumbers SUB ##
####################
sub getNumbers
{
   $line = <STDIN>;
   $line =~ s/^\s+|\s*\n$//g;
   split(/\s+/, $line);         ## this is the return value
}

####################
####    Main    ####
####################
$total = 0;
foreach $number (&getNumbers)      ## can even call subroutines from the for loop
{
   $total += $number;
}
print ("\nThe total is: $total\n");

Return statement ####################
## getDummy SUB ##
####################
sub getDummy
{
   $dummy_value = 1000000;
   $line = <STDIN>;
   $line =~ s/^\s+|\s*\n$//g;
   split(/\s+/, $line);
   return $dummy_value;      ## We return a value other than the last expression value
}

####################
####    Main    ####
####################
print ("\nThe dummy_value is " . &getDummy );

Note: we can use the keyword return to return a different value than the last expression

Local Variables

There are two statements that define local variables

my

####################
### localVar SUB ###
####################
sub localVar
{
   my $total = 100;        ## defining a local variable with my keyword
   return $total;
}

##################
###    Main    ###
##################
$total = 10;
print ("Local total is $total\n");
print ("Subroutine local total is " . &localVar)

local you can use local keyword instead of the my keyword. The only difference between the two is that my variables are not know outside the subroutine.

Passing values to a subroutine

You make subroutines more flexible by allowing them to accept values passed from the main or any other subroutine program; these values passed are known as arguments. When passing the arguments to a subroutine they are placed in the system array variable @_, it is create whenever you pass arguments to a subroutine.

Passing values to subroutines

########################
## whoDoYouupport SUB ##
########################
sub whoDoYouSupport
{
my ($team, $home, $crowd) = @_;        # place the passed arguments into local variables getting them
                                       # from the system array variable @_

print("Team: $team\n");
print("Home Ground: $home\n");
print("Capacity: $crowd\n");

print ("system array variable first element is " . $_[0]);    # acts just like any normal array
}

##################
###    Main    ###
##################
$footballTeam = "Milton Keynes Dons";
$ground = "MK Stadium";
$capacity = 30000;

&whoDoYouSupport($footballTeam, $ground, $capacity);   # pass the arguments to the subroutine

Passing lists to subroutines #####################
###  getLists SUB ###
#####################
sub getLists
{
   my (@localList) = @_;           # all the lists will be merged into a single array @_

   foreach $number (@localList)
   {
      print("$number\n");
   }
}

##################
###    Main    ###
##################
$num_one = 1;
@num_list = qw( 2 3 4 5);
$num_six = 6;

&getLists($num_one, @num_list, $num_six);      # pass all the lists as arguments

Calling subroutines from subroutines

####################
### routine1 SUB ###
####################
sub routine1 {
   &routine2;    # call subroutine routine2
}

####################
### routine2 SUB ###
####################
sub routine2 {
   print("You called subroutine two from subroutine one\n");
}

##################
###    Main    ###
##################
&routine1;

Recursive subroutines

#####################
### rightcalc SUB ###
#####################
sub rightcalc {
   my ($index) = @_;
   my ($result, $operand1, $operand2);

   if ( $index+3 == @list )
   {
      $operand2 = $list[$index2+2];
   }
   else
   {
      $operand2 = &rightcalc($index+2);
   }
   $operand1 = $list[$index+1];
   if ($list[$index] eq "+" )
   {
      $result = $operand1 + $operand2;
   }
   elsif ($list[$index] eq "*" )
   {
      $result = $operand1 * $operand2;
   }
   elsif ($list[$index] eq "-" )
   {
      $result = $operand1 - $operand2;
   }
   else
   {
      $result = $operand1 / $operand2;
   }
}

##################
###    Main    ###
##################
$inputline = <STDIN>;$inputline =~ s/^\s+|\s+$//g;
@list = split(/\s+/, $inputline);
$result = &rightcalc(0);
print ("The result is $result\n");

Passing arrays by name using aliases

##################
###  my_sub    ###
##################
sub my_sub {
   local (*subarray) = @_;      # tells the perl interpreter to operate on the actual list

   foreach $number (@subarray) {
      print($number . "\n");
   }
}

##################
###    Main    ###
##################
@list = qw( 1 2 3 4 5);
&my_sub(*list);                 # the argument *foo indicates that the array @foo is to be passed to
                                # my_sub and aliased

BEGIN and END subroutines

exit;
print("should not see this as it is after exit statement\n");
BEGIN { print("This will always execute\n") };
END { print("This will also always execute even you you stop the program with die or exit\n")};

AUTLOAD (non-existent subroutines

@list = qw( 1 2 3 4);
&crazysun(@list);

AUTOLOAD { print("subroutine $AUTOLOAD does not exist check your code\n"); }

Note: useful if you have very large scripts or have many perl modules

Formatting Output

Perl enables you to produce formated output using print formats and the built-in function write.

Using Print Format

Defining format MYFORMAT =                           # start with the format keyword
===================================
Here is the text i want to display.
===================================
.                                           # terminated by a single dot
Display a print format

$~ = "MYFORMAT";                            # set the system variable $~ to the format you want to use
write;                                      # call the built-in write function

format MYFORMAT =                                 
===================================
Here is the text i want to display.
===================================
.                                           # don't forget the single dot

Displaying Valuesin a Print Format

$line = "hello this is a test program";

$line =~ s/[^aeiou]//g;
@vowels = split(//, $line);
foreach $vowel (@vowels)
{
   $vowelcount{$vowel} += 1;
}

$~ = "MYFORMAT";
write;

format MYFORMAT =
=====================================================
Number of vowels found in text file:
      a: @<<<<< e: @<<<<<
      $vowelcount{"a"}, $vowelcount{"e"}
      i: @<<<<< o: @<<<<<
      $vowelcount{"i"}, $vowelcount{"o"}
      u: @<<<<<
      $vowelcount{"u"}
=====================================================
.

Note: the @<<<<< means six left justified characters

There are a number of fields formats that can be used

Left-Justified output @<<<       # 4 left-justified characters ( (@=1 character) + (<<<=3 characters) ) = 4 characters total
@<<<<<     # 6 left-justified characters
Right-Justified output @>>>
@>>>>>
Centered output @||||      # 4 centered characters
Fixed-precision numeric @##.##     # 3 numbers before decimal point 2 numbers after example 345.78
Multiline text @*         # any length

There are other formating utilies

Specifying a Page Number

$~ = "PAGE_FOOTER";
write;

format PAGE_FOOTER =
page @<<<
$%
.

Note: the system variable $% holds the current page number and starts from 0

Set the page length $= = 66;             # system variable $= hold the page length
Change the Header Print Format $~ = "MYFORMAT";
$^ = "TOP_OF_PAGE";
write;

format MYFORMAT =
myformat
.
format TOP_OF_PAGE =
top of the page
.

Balance formatting and removing blank lines $string = ("this is a\n line of string to\n confuse outputting

added a couple of blank lines \n");

$~ = "MYFORMAT";
write;

format MYFORMAT =
~ ^>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
$string
.

Note: the ^<< trys to fit as many lines as possible, @* will print as is including newlines
~ will remove any blank lines

Putting it all together

open (OUTFILE, ">file1");
select (OUTFILE);
$~ = "WRITELINE";
$^ = "TOP_OF_PAGE";
$= = 60;

while ($line = <STDIN>)
{
   write;
}

close (OUTFILE);

format TOP_OF_PAGE =
                    -Page @<
                          $%
.
format WRITELINE =
@>>>>>>>>>>>>>>>>>>>>
$line
.

Using printf

Perl borrows from the C language the printf function and is used just the same, the field specifiers are below

Single Character %c
Integer %d
Floating-point in scientific notation %e
Floating-point in normal fixed-point notation %f
Floating-point in compact format %g
Integer in octal %o
Character String %s
Unsigned integer %u
nteger in hex format %x
Examples

printf("The number is %d", $number);
printf("The house number is %d and the town is %s", $number, $town);

printf("amount: %20d", $salary);     # 20 fields of characters (right justified)
printf("amount: %-20d", $salary);    # 20 fields of characters (left justified)

printf("sale cost: %5.2f", $cost);   # 5 = total number of fields including the decimal point
                                     # 2 = total numbers after decimal point example:   99.99

Process, String and Mathematical Functions

Perl provides a wide range of functions that manipulate both the program currently being executed and other programs (also called processes) running on your machine, they are divided into four groups

Starting a Process

Several built-in functions provide different ways of creating process

eval The eval function treats a character string as an executable Perl program. Eval function is best used for small programs for large programs it is better to use the system function
system When system is called it starts a process that runs the program passed to it and waits until the process terminates. This function is passed a list as follows; the first element of the list contains the name of a program to execute and the other elements are arguments to be passed to the program .
fork

The fork function creates two copies of your program, the parent process and the child process. Fork returnes zero to the child process and a non-zero value to the parent process, this non-zero value is the process ID of the child process.

Becareful when using fork

  • if both copies of the program execute calls to print or any other output-generating function, the output from one copy might be mixed with the output from the other copy.
  • if you use fork in a loop, the program might wind up generating many copies of itself.
  • your child process might wind up executing code that your parent process is supposed to execute, or vice versa.
pipe The pipe function is designed to be used in conjunction with the fork function. It provides a way for the child and parent process to communicate.
exec The exec function is simular to the system function, except that it terminates the current program befre starting a new one. This function is passed a list as follows; the first element of the list contains the name of a program to execute and the other elements are arguments to be passed to the program.
syscall The syscall calls a system function, This function is passed a list as follows; the first element of the list contains the name of a program to execute and the other elements are arguments to be passed to the program
Examples
eval

## Example one
$print = "print (\"hello world\\n\");";
eval ($print);

## Example two (this has a error)
$print = "print (\hello world\\n\");";     # I have removed a double quote
eval ($print);
print "Errors: " . $@                      # $@ will contains the error message

Note: the $@ system variable is used to indicate if the statement was executed properly, if no error $@ contains null, if any errors $@ will have the error message

system

@proglist = ("echo", "hello", "world");     # echo is the program, hello world are the arguments to echo
system(@proglist);

Note: sometimes it is use to use the below command to make sure that buffers are flushed immediately, as sometimes calling two systems duplicate outp[ut can be mixed

$| = 1;       # make sure output buffers are flushed immediately.

fork

print "Parent PID: " . $$ . "\n";

$retval = fork();

if ($retval == 0) {
   # this is the child process
   print $retval . "\n";
   print "Child PID: " . $$ . "\n";
   exit;
} else {
# this is the parent process
}

Note: to terminate a child process you use the exit function which is discussed lter

pipe # pipe (infile, outfile)
pipe (INPUT, OUTPUT);     # Data sent to OUTPUT can be read from INPUT

$retval = fork();

if ($retval != 0) {
   # this is the parent process
   close (INPUT);         # the parent process does not need INPUT
   print "Enter a line of input: ";
   $line = <STDIN>;
   print OUTPUT ($line);
} else {
   # this is the child process
   close (OUTPUT);        # the child process does not need OUPUT
   $line = <INPUT>;       # because data from OUTPUT is piped into INPUT, the program waits until the
                          # data is actually sent before continuing
   print ($line);
   exit(0)
}

exec

exec ("vi", "test.pl");

Note: exec has the same buffering problems as system

syscall

require ("syscall.ph");   # must have the syscall header

my $buf = "\0"x64;
my $path = "/etc/motd";

syscall(&SYS_statfs, $path, $buf) == 0 or die;

my ($bsize, $blocks, $bfree, $bavail, $files, $ffree, $namelen) = unpack "x4 L6 x8 L", $buf;

print <<EOT;
   Optimal transfer block size: $bsize
   Blocks in file system: $blocks
   Blocks free: $bfree (${\(int $bfree/$blocks*100)}%)
   User blocks available: $bavail (${\(int $bavail/$blocks*100)}%)
   Inodes: $files
   Free inodes: $ffree (${\(int $ffree/$files*100)}%)
   Maximum filename length: $namelen
EOT

Terminating a Program or Process

Several built-in functions provide different ways of terminating a program or process

die The die function terminates a program and prints an erropr message on the standard error file
warn The warn function like the die function prints a message on the standard error file but does not terminate the program
exit The exit function terminates a program and can optionally return a code value.
kill The kill function enables you to send a signal to a group of processes.
Examples
die die ("message");         # prints the message and program name and line number where the error occurred
die ("message\n");       # only prints the error message
warn warn ("message");        # prints the message and program name and line number where the error occurred
warn ("message\n");      # only prints the error message
exit exit();
exit(8);                 # exits and retruns the code 8
kill @proclist = qw(5555 5556 5557);

kill (9, @proclist);     # send a kill signal 9 to processes 5555 5556 5557

Execution Control

Several built-in functions provide different ways of to delay a program or process

sleep The sleep function suspends the program for a specified number of seconds
wait The wait function suspends execution and waits for a child process to terminate (such as a process created by fork)
waitpid The waitpid function waits for a particular child process.
Examples
sleep sleep (5);                # sleep for 5 seconds;
wait wait();                   # wait returns the process ID, -1 is returned if no child process exists
waitpid

# waitpid (<procid>,<waitflag>)

$procid = fork();                                    # obtain the child process ID

if ($procid == 0) {
   # this is the child process
   print ("CHILD: this line is printed first\n");
   exit(0);
} else {
   # this is the parent process
   waitpid ($procid, 0);                              # wait until child process finishes
   print ("PARENT: this line is printed first\n");
}

Note: the waitflags are
0  - normal wait
1  - process has been found and has terminated
-1 - child process does not exist

Miscellaneous Control Functions

Several built-in functions provide different ways of to perform various process and program-related actions

caller

The caller function returns the name and line number of the program that called the currently executing subroutine.

caller returns a three-element list subinfo consisting of the following

  • The name of the package from which the subroutine was called
  • The name of the file from which the subroutine was called
  • The line number of the subroutine call

The function is mainly used with the perl debugger.

chroot The chroot function duplicates the functionality of the chroot function call.
local The local function declares that copy of a named variable is to be defained for a subroutine
times

The times function returns the amount of job time consumed by this program and any child processes of this program

times returns timelist a list consisting of the following pointing float numbers

  • The user time consumed by this program
  • The system time consumed by this program
  • The user time consumed by child process
  • The system time consumed by child process
Examples
caller test();

sub test {
   ($package, $file, $line_num) = caller;

   print "Package: " . $package . "\n";
   print "File: " . $file . "\n";
   print "Line Number: " . $line_num . "\n";
}

chroot # chroot(dir)
chroot ("/export/home/pvalle");      # the specified directory becomes the root directory for the program
local

if ( $var == 44) {
   local ($localvar);                # this is a local variable and does not affect any other $localvar's
}

Note: becarefuil when using loops as you can create alot of local variables

times $procid = fork();

($user,$system,$cuser,$csystem) = times;   # The four element list is returned

if ($procid == 0) {
   # this is the child process
   print ("CHILD: this line is printed first\n");
   exit(0);
} else {
   # this is the parent process
   waitpid ($procid, 0); # wait until child process finishes
   print ("PARENT: this line is printed first\n");
}

print "User: " . $user . "\n";
print "System: " . $system . "\n";
print "Child User: " . $cuser . "\n";
print "Child System: " . $csystem . "\n";

Mathematical Functions

Perl provides lots of mathematical functions

sin pass in a scalar value and the sine value is returned
cos pass in a scalar value and the cosine value is returned
atan2 calculates and returns the arctangent of one value dividend by another in the range -∏ to ∏
sqrt returns the square root value of the value passed
exp returns the e ** value
log takes a value and returns the natural (base e) logarithm of the value
abs returns the absolute value of a number
rand passed a integer value and returns a random floating point number between zero and value passed
srand use the random number generator used by rand, this ensures that the random numbers are truely random
Examples
sin $retval = sin (<value>);
cos $retval = cos (<value>);
atan2 $retval = atan2 (<value1>, <value2>);
sqrt $retval = sqrt (<value>);
exp $retval = exp (<value>);
log $retval = log (<value>);
$retval = log (exp ($var));      # The log function undoes exp expression
abs $retval = abs (<value>);
rand $retval = rand(<num>);           # any random number between 0 and specified number
srand $retval = srand(<num>); 

String-Manipulation Functions

There are many functions that can manipulate strings

index provides a way of indicating the location of a substring in a string
rindex the same as index but starts at the right-hand side of the string
length returns the number of characters of a string
tr the translate functions translates character from one set into a diffferent set, you can also obtain the number of characters in a string
pos returns the location of the last pattern match in a string, you can use the global pattern match operator.
substr lets you assign a part of a character string to a scalar variable
study is a special function that tells the interpreter that the specified scalar variable is about to be searched many times.
lc and uc lc converts a string to lower case, uc converts a string to upper case
lcfirst and ucfirst lcfirst converts the first character of a string to lower case, ucfirst converts the first character of a string to upper case
quotemeta places a \ in front of any non-words
join takes a list and joins it into a single string
sprintf The sprintf function is the same as the printf function, except that the formated string is returned by the function instead of being written to a file
Examples
index

# position = index (string, substring)
# position = index (string, substring, skip characters)

$string = "elephant";
$position = index($string, "ant");

print "ant is located at position " . $position . " in elephant";

rindex

# position = rindex (string, substring)
# position = rindex (string, substring, skip characters)

$string = "elephant";
$position = rindex($string, "ant");

print "ant is located at position " . $position . " in elephant";

Note: the only different with index and rindex is thet rindex starts at the right hand side of the string

length $string = "elephant";

print "There are " . length($string) . " characters in elephant";
tr $string = "elephant";
$_ = $string;                    # tr uses the system variable $_;

$new_string = tr/a-z/A-Z/;       # new string goes in $_, number of characters change is returned

print "We have changed " . $string . " to " . $_ . "\n";
print $string . " has " . $new_string . " characters"

pos

$string = "Mississippi";

while ($string =~ /i/g) {
   $position = pos($string);
   print ("matched at position $position\n");
}

substr

# substr (expr, skipchars, length)

$string = "This is a simple character string";

$sub1 = substr($string, 10 , 6);       # skip 10 characters, get next 6 characters
$sub2 = substr($string, 17);           # skip 17 characters, get the rest of the string

print '$sub1 is ' . $sub1 . ' and $sub2 is ' . $sub2;

study study ($myvar);
lc and uc $lower = lc("Hello");                  # returns hello
$upper = uc("hello");                  # returns HELLO
lcfirst and ucfirst $lcfirst = lcfirst("Hello");           # returns hello
$ucfirst = ucfirst("hello");           # returnsd Hello
quotemeta $string = "Hello World";

$newstring = quotemeta($string);

print $string . "\n";
print $newstring;                      # prints 'Hello\ World'

join @list = qw ( hello what a wonderful day);

$string1 = join( "::", @list);
$string2 = join( " ", @list);

print $string1 . "\n";
print $string2;

sprintf

$num = 26;
$outstr = sprintf("%d = %x hexadecimal or %o octal\n", $num, $num, $num);

print $outstr;

Scalar-Conversion Functions

There are many functions in Perl that convert scalar values from one form to another and functions that deal with variables that have not had values defined for them.

chop it removes the last character from a scalar value or a list
chomp chomp removes the last character/s only if it matches the system variable $/, you can use chomp on a scalar value or a list
crypt this function encrypts a string using the NBS Data Encryption Standard (DES) algorithm, the algorithm uses a salt key to make it more differcult to decode, the salt key is 2 characters in length, these two characters can be any leter or digit or one of the . and / characters.
hex this function assumes that a character string is a number written in hexadecimal format and converts it into a decimal number.
int this function turns a floating point number into a integer by remove everything after the decimal point
oct this function assumes that a character string is a number written in octal format and converts it into a decimal number.
ord and chr ord converts a single character to its numeric ASCII equivalent
chr converts a number to its ASCII character equivalent
scalar The scalar function enables you to specify the scalar meaning in an array context.
vec enables you to treat a scalar value as a collection of chunks, with each chunck consisting of a specified number of bits, this collection is known as a vector. Each call to vec accesses a particular chunk of bits in the vector (known as a bit vector).
define the define functions checks to see if a variable has been
undef undefines a scalar variable, array element or an entire array, basically means that it appears that the variable, element or array has never been assigned.
Examples
chop

$string = "hello World!";
chop ($string);                       # string is now "Hello World", removed the bang (!)
                                      # chop returns the last character chopped in this case the !

@list = qw ( one two three );
chop (@list)                          # list is now "on","tw","thre"
                                      # chop returns the last character chopped in this case e

Note: chop is normally used to remove the newline character when requesting user input from <STDIN>

chomp $string = "hello";
@list = qw( one two three );

$/ = "o";                             # remove the last character only if it's a 'o'
chomp $string;

$/ = "e";                             # remove the last character only if it's a 'e'
chomp @list;

print $string . "\n";
print "@list";                        # notice only one and three get chomped because they have a 'e'
                                      # as the last character

Note: you can chomp multiple characters as well

crypt $salt_key = "3h";                     # the salt key is 2 characters and can be any digit, character or
                                      # a dot (.) or forward slash (/)

print "Enter something to encrypt: ";

$encrypt = <STDIN>;

print "\n Your text encrypted: " . crypt($encrypt, $salt_key);   

Note: DES uses a salt key to change the DES algorithm to make it more differcult to decode.

hex $hex = "ffff";

print hex($hex);                     # prints out 65535

int $float = 34.56;

print int($float);                   # prints out 34

oct $octal = 177;

print oct($octal);                   # prints out 127

ord and chr $char = 'V';

print ord($char) . "\n";

print chr(ord($char));               # using ord to obtain the numeric ASCII of V (86)

scalar @array = qw (a b c);

@lengtharray = scalar(@array);

print "@lengtharray" . "\n";         # number of array elements of @array (3), is converted into a one
                                     # element list and assigned to @lengtharray

$| = 1;

print "Enter a string: \n";
@line = scalar (<STDIN>);            # specifying scalar with <STDIN> ensures that only one lin is read
                                     # from STDIN

print "@line";

vec # retval = vex (vector, index, bits)
$vector = pack ("B*", "11010011");

$val1 = vec ($vector, 0, 4);         # start at right get 0011 (4 bits) = 3 in decimal
$val2 = vec ($vector, 1, 4);         # start at left get 1101 (4 bits) = 13 in decimal

print ("high-to-low order values: $val1 and $val2");

Note: specifying 0 means start at the right end, 1 means start at the left end

define $array[1] = "hello";

if (defined ($array[0])) {
   print "element 0 in array is defined\n";
} else {
   print "element 0 in array is NOT defined\n";
}

if (defined ($array[1])) {
   print "element 1 in array is defined\n";
} else {
   print "element 1 in array is NOT defined\n";
}

undef undef ($myvar);
undef ($array[2]);
undef (@array);

Pack Function

The pack function enables you to take a list or the contents of an array variable and convert (pack) it into a scalar value in a format that can be stored in actual machine memory or used in programming languages such as C.

You use a packformat to determine how the list is to be packed, there are many packformat options

a ASCII character string padded with null characters
A ASCII character string padded with spaces
b String of bits, lowest first
B String of bits, highest first
c A signed character (range usually -128 to 127)
C An unsigned character (usually 8 bits)
d A double-precision floating-point number
f A single-precision floating-point number
h Hexadecimal string, lowest digit first
H Hexadecimal string, highest digit first
i A signed integer
I An unsigned integer
l A signed long interger
L A unsigned long interger
n A short integer in network order
N A long integer in network order
p A pointer to a string
s A signed short interger
S A unsigned short interger
u Convert to uuencode format
v A short integer in VAX (little-endian) order
V A long integer in VAX order
x A null byte
X Indicates "go back one byte"
@ Fill with nulls (ASCII 0)

Here are some examples

Example One

$integer = pack("i", 171)

$integer = pack("i*", 14, 26, 11, 241);

Note: takes number 171 converts it into the format used to store integers on your machine and returns the converted integer in $integer. This converted integer can now be written out to a file or passed to a program using system or exec functions

Example Two

$mystring = pack("a6", "test");

Note: This creates a string of 6 characters (4 for the word test and 2 null characters for padding)

Example Three

$mystring = pack("a @6 a", "test", "test2");

Note: This integer indicates the number of bytes the string must contain at this point. here the test string is convert to ASCII format, because this string is only 4 characters long, and the pack format @6 specifies that it should be 6 characters two null characters are added to the string before test2 is packed.

Pack Function and C data types

The most frequent use of pack is to create data that can be used by C programs

Pack and C data types $Cstring = pack ("ax", $mystring);         # a = ASCII character string padded with null characters
                                           # x = a null byte

Note: pack converts $mystring into an ASCII string, and the x character appends a null character to the end of the string. This format - a string followed by null - is how C stores strings.

Unpack Function

The unpack function reverses the operation performed by pack. It takes the value stored in machine format and converts it to a list of values understood by Perl

unpack $mystring2 = unpack("a6", $mystring);

print $mystring2;

unpack and skipp characters

$skipnum = unpack("@4i", $mystring);

Note: the @4 means skip 4 bytes then unpack

Unpack Function and uuencode

The unpack function enables you to decode files that have been encoded by the uuencode encoding program.

decode a uuencoded string $decoded = unpack("u", $uuencoded_line);