Вы находитесь на странице: 1из 232

1

Table of Contents
What is Perl? 5
Where to Find Perl 6
What is CPAN? 7
Documentation 7
Perl Scripts 9
Print Functions 10
Literals 12
Quoting Rules 15
Here Documents 17

Variables 23
Naming Conventions 23
Scope and Package 23
Scalars 26
Assigning a value to a Scalar Variable 26
The $_ scalar variable 27
Arrays 28
Array slices 30
Some Array Functions 31
Associative Arrays (Hashes) 39
Reading From STDIN 41
<STDIN> Standard Input 41
Special Hashes 43
The %SIG Hash (Handling Signals) 44

Operators 49
Precedence and Associativity 49
Arithmetic Operators 51
Assignment Operators 51

Basic Perl © 2006 Learning Enterprises, Inc.


2 Module 1

Relational Operators 52
Equality Operators 55
Logical Operators 58
Autoincrement and Autodecrement Operators 59
String Operators 60
Range Operator 62
Generating Random Numbers 62

Conditional Statements and Loops 65


If/else 65
unless/else 65
Loops 68
The while loop 68
The until loop 69
The for loop 70
The foreach loop 72
Loop Control 73

Pattern Matching 79
Simple Statements and Modifiers 79
Matching and Substitution Operations 82
The match operator 82
The substitution operator 83
Pattern Matching Operators 87
The RE Metacharacters 89
The Dot 92
Character Sets 94
Metasymbols to Represent Single Characters 95
Quantifiers ( * + ? ) 96
Alternation 97
Grouping 98

Basic Perl © 2006 Learning Enterprises, Inc.


3

Capturing Patterns ($1 $2 $3 ... ) 99


Repeating Patterns 101

User–Defined Filehandles 105


A Little About Dying 105
Open a File for Reading 106
Close a File 106
Open a File for Writing 108
Open a File for Appending 108
Finding a Position in a File 109
File Testing 112
Passing Arguments to a Script 114
The ARGV Array 114
ARGV and the Null Filehandle 115

Subroutines 121
Arguments/Parameters 124
The Return Statement 127
Packages 128
The Symbol Table 129
Using the strict Pragma in Packages 132
The Standard Perl Library 134
Using a Perl5 Module from the Standard Perl Library 136

Hard References (Pointers) 145


Anonymous Variables and References 146
Using Data::Dumper 151

Object Oriented Perl 157


OOP Terms 158
Classes 159

Basic Perl © 2006 Learning Enterprises, Inc.


4 Module 1

Objects 159
Methods 162
Destructors and Garbage Collection 169
Inheritance 170
Documenting Modules 175
Pod Files 175
Using the Expect.pm Module from CPAN 188
Using a Juniper Library 194
Perl Debugger 218

Basic Perl © 2006 Learning Enterprises, Inc.


Getting with it Syntactically 5

Module 1
Getting with it Syntactically
1.1 What is Perl?
• Perl stands for Practical Extraction and Report Language. Perl is an inter-
preted language, combining all the best features of the Shell, C, awk, grep,
and sed. It is used for extracting text from files, system administration
chores, and report writing.
• Perl was written by Larry Wall and released to the net in 1989. It has been
through two major revisions and is currently version Perl 5.8.8.
• The main distribution point for Perl is CPAN, the Comprehensive Perl
Archive Network at www.perl.com or www.perl.org. The main ftp site is
ftp.funet.fi (128.214.248.6).

• Perl behaves like awk, grep, and sed.


• Perl behaves like C and C++.

• Perl behaves like the Shell.

Basic Perl © 2006 Learning Enterprises, Inc.


6 Module 1

1.2 Where to Find Perl


FIGURE 0.1 The Perl Home Page

Basic Perl © 2006 Learning Enterprises, Inc.


Getting with it Syntactically 7

1.3 What is CPAN?


• “CPAN ( the Comprehensive Perl Archive Network) is the central
repository for everything Perl. It contains the collected wisdom of the entire
Perl community: hundreds of Perl modules and scripts, several books’ worth
of documentation, and the entire Perl distribution.”1

• CPAN contains all the free Perl material you will ever need, including
documentation, faqs, scripts, binary distributions and source code, and
announcements. CPAN is mirrored all over the world and you can find the
nearest mirror at:
http://www.perl.com/CPAN
http://www.cpan.org

• CPAN is the place you will go if you want to find modules to help you
with your work. The CPAN search engine will let you find modules under
a large number of categories.

1.4 Documentation
• The standard Perl distribution comes with complete online documentation
called man pages, stemming from the Unix man pages (manual pages) pro-
viding help for all the standard utilities. Perl has divided its man pages into
categories. If you type at your command line prompt:

man perl

• To get a specific category, e.g. help on how to use Perl’s regular expres-
sions, type:
man perlre

and for help on subroutines, type:


man perlsub
• The categories are as follows:
perlbot Perl object-oriented tricks and examples
perldebug Perl debugging
perldiag Perl diagnostic messages
perldsc Perl data structures: intro
perlform Perl formats

1. Programming Perl, O’Reilly, Larry Wall, Tom Christianson & Jon Orwant, 3rd Edition, July 2000, p. 547.

Basic Perl © 2006 Learning Enterprises, Inc.


8 Module 1

perlfunc Perl builtin functions


perlipc Perl interprocess communication
perllol Perl data structures: lists of lists
perlmod Perl modules
perlobj Perl objects
perlop Perl operators and precedence
perlpod Perl plain old documentation
perlre Perl regular expressions
perlref Perl references
perlsock Perl extension for socket support
perlstyle Perl style guide
perlsub Perl subroutines
perltie Perl objects hidden behind simple variables
perltrap Perl traps for the unwary
perlvar Perl predefined variables

• If you want to find out how a builtin function works, use the -f option fol-
lowed by the name of the function, as follows:

perldoc -f print
perldoc -f localtime

• If you are trying to find out how a particular library module works, you
can use the perldoc command to get the documentation. For example, if you
want to know about the CGI.pm module, type at the command line:

perldoc CGI

The documentation for the CGI.pm module will be displayed, and if you
type:
perldoc English

The documentation for the English.pm module will be displayed.


Perl 5.6.1 allows you to search for information from the man pages by using
the name of the man page as a command (like grep), followed by the pattern
you are searching for. For example: perlvar hash will search for the term
hash in the perlvar section of the man pages whereas perlfunc printf will
search for the pattern printf in the perfunc section.

Basic Perl © 2006 Learning Enterprises, Inc.


Getting with it Syntactically 9

1.5 Perl Scripts


• Perl scripts are like shell, sed, and awk scripts.
• The first line contains the #! symbol followed by the full pathname of
the directory where your version of Perl resides. This tells the kernel
what program is interpreting the script.
• Comments are lines preceded with the pound sign.
• In Perl scripts, each statement is terminated with a semi–colon.
• The execute permission must be turned on in order for the perl script
to be executed directly.
• The Web server needs both read and execute permission for CGI scripts.
• If using the vi editor, press ESC and type a colon. At the colon
prompt, type:
:0r !which perl
This reads into your script (on line0 ) the correct pathname for
your version of perl.

Example 1.1
$ cat first.plx
1 #!/usr/bin/perl
2 # My first try at perl
3 print “Hello to you and yours!\n”;

4 $ chmod +x first.plx Turn on execute permission


or
$ chmod 755 first.perl

5 $ perl –c first.plx Check script syntax


6 first.plx syntax OK
$

7 $ first.plx
8 Hello to you and yours!

• To run the script without using the #! line or chmod, give the perl script
name as an argument to the perl interpreter as follows:

$ perl first.plx

Basic Perl © 2006 Learning Enterprises, Inc.


10 Module 1

1.6 Print Functions


1.6.1 The print function

• The print function prints a string or a list of comma separated strings to


the standard output.
• The standard output, STDOUT, is called a Perl filehandle and is the
default filehandle for print.
• The “\n” adds a newline to the end of the string.
• The “\n” can be embedded in the string or treated as a separate string.

Example 1.2

$ perl –e ’print “hello there\n”, “how are you?”,“\n”;’


hello there
how are you?

1.6.2 The printf function

• Similar to the printf function of C and Awk.


• Used when formatting is needed.
• Sends output to STDOUT filehandle, the screen.
• Consists of a quoted format string that may include format
specifications, including a dash for left justified text.
• Format specifications consist of a percent sign followed by a
conversion character. Each format specification has a corresponding
argument after the quoted string.

Example 1.3

$ perl –e ’printf”|%-5d%-10s%10.2f|.\n”, 10, ”Tom” ,5;’


|10 Tom 5.00|.

Prints a 5 space, left justified decimal value (%-5d), followed by a left-justified 10


space string (%-10s), followed by a right justified 10 space floating point number
where three of the spaces are held by the decimal point, followed by the two num-
bers after the decimal point (%10.2f).

Basic Perl © 2006 Learning Enterprises, Inc.


Getting with it Syntactically 11

The printf Conversion Characters

Conversion Character Definition


b Binary
c Character
s String
d Decimal number
x Hexadecimal number
o Octal number
e Floating point number in scientific notation
f Floating point number

Example 1.4
( The Script )
#!/usr/bin/perl
1 printf “Hello to you and yours %s!\n”,”Sam McGoo”;
2 printf “The number in decimal is %d\n”, 45;
3 printf “The formatted number is |%10d|\n”, 100;
4 printf “Left justified the number is |%–10d|\n”,100;
5 printf “The number in octal is %o\n”,15;
6 printf “The number in hex is %x\n”, 15;
7 printf “The floating point number is |%8f|\n”, 15;
8 printf “The formatted floating point number is |%8.2f|\n”, 14.3456;
9 printf “The character is %c\n”,65;
10printf “The number in scientific notation is %e.\n”, 15.25;
11 printf"The binary value is %b\n", 0b1110;
12 printf"The binary value is %b\n", 15;

( The Output )
1 Hello to you and yours Sam McGoo!
2 The number in decimal is 45
3 The formatted number is | 100|
4 Left justified the number is |100 |
5 The number in octal is 17
6 The number in hex is f
7 The floating point number is |15.00000|
8 The formatted floating point number is | 14.35|
9 The character is A.
10The number in scientific notation is1.525000e+01.
11The binary value is 1110
12 The binary value is 1111

Basic Perl © 2006 Learning Enterprises, Inc.


12 Module 1

1.7 Literals
1.7.1 Numeric Literals

Example 1.5
12345 integer
23.45 float
.234E–2 scientific notation
0x456fff hexadecimal
0777 octal
0b111 binary (Perl 5.6)

1.7.2 Printing Literals

Example 1.6
(The Script )
#!/usr/bin/perl
# Program to illustrate printing literals
1 print “The price is \$”,100, ”.\n”;
2 print “The number is ”,0777,”.\n”;
3 print “The number is ”,0xAbcF,”.\n”;
4 print “The unformatted number is ”, 14.56, ”.\n”;
5 printf “The formatted number is %f\n”, 14.56;
6 printf “The formatted number is %.2f\n”, 14.56;
7 print "The binary value 1110 is ", 0b1110, ".\n";

( Output )
1 The price is $100.
2 The number is 511.
3 The number is 43983.
4 The unformatted number is 14.56.
5 The formatted number is 14.560000
6 The formatted number is 14.56
7 The binary value 1110 is 14.

Basic Perl © 2006 Learning Enterprises, Inc.


Getting with it Syntactically 13

1.7.3 String Literals

• Strings containing string literals are delimited by double quotes for back-
slash and variable substitution.

Escape Sequence What it Represents

\t tab
\n newline
\r return
\f form feed
\b backspace
\a alarm
\e escape
\033 octal character
\xff hexadecimal character
\c[ control character
\l next character lower case
\u next character upper case
\L lower case until \E
\U upper case until \E
\Q backslash all following non-alphanumeric characters until \E is found
\E ends upper or lower case conversion started with \L or \U or \Q
\\ backslash

Example 1.7
(In Script)
1 #!/usr/bin/perl
2 print “***\tIn double quotes\t***\n”; # backslash interpretation
3 print ’%%%\t\tIn single quotes\t\t%%%\n’; # All characters are printed as literals
4 print “\n”;

(Output)
1 *** In double quotes ***
2 %%%\t\tIn single quotes\t\t%%%\n

Example 1.8
(In Script)
1 print “\a\t\tThe \Unumber\E \LIS\E ”,0777,”.\n”;
2 # Alarm followed by 2 tabs, the string “The”, the string “number” to be printed
#in upper case, the string “is” to be printed in lower case, the decimal value for
# octal 0777, and the newline character.

(Output)
1 (BEEP) The NUMBER is 511.

Basic Perl © 2006 Learning Enterprises, Inc.


14 Module 1

1.7.4 Special Literals


(Use two underscores before and after the literal.)

_ _LINE_ _ represents the current line number

_ _FILE_ _ represents the current filename

_ _END_ _ represents the logical end of the script; trailing garbage is


ignored.

_ _DATA_ _ Also represents the logical end of the script; used with
<DATA> filehandle so that text can be read from the
script rather than from an external file.

Example 1.9
(In Script)
#!/usr/bin/perl
1 # Program to test special literals
2 print ”We are on line number ”, __LINE__, ”.\n”;
3 print ”The name of this file is ”,__FILE__ ,”.\n”;
4 __END__
And this stuff is just a bunch of chitter–chatter that is to be ignored by perl.
The __END__ literal is like cntrl–d or \004. ( See –x switch ).

(Output)
2 We are on line number 3.
3 The name of this file is literals.sp.

Example 1.10
(The Script)
#!/usr/bin/perl
# Program, named literals.perl2, written to test special literal __DATA_
1print <DATA>;
2__DATA__
This line will be printed.
And so will this one.

Output:
This line will be printed.
And so will this one.

Basic Perl © 2006 Learning Enterprises, Inc.


Getting with it Syntactically 15

1.7.5 Words
• Words consist of alphanumeric characters and underline
• Words must start with an alphanumeric character.
• If all lowercase, a word could conflict with future reserved words. A word
that has no other meaning to Perl will be treated as though it were enclosed
in single quotes.
• If the first word after print is not quoted, Perl treats it as a filehandle; there-
fore the filehandle, STDOUT, must be placed after print.
• As a rule of thumb, surround any bare words with either a pair of single or
double quotes.

1.7.6 The –w switch and the warnings pragma


• Used to warn you about the possibility of using future reserved words.
From the Perl5 man page, ”Whenever you get mysterious behavior, try the
–w switch!! Whenever you don’t get mysterious behavior, try the –w switch
anyway.” (Larry’s humor).
• A pragma is a special Perl module that hints to the compiler the way that
a block of statements should be compiled. You can use this type of module
to help control the way your program behaves. Starting with Perl version
5.6.0, “warnings.pm” was added to the standard Perl library; it is a pragma
that allows you to control the types of warnings printed, similar to the -w
switch. To turn on warnings, type: use warnings at the top of your script.

1.8 Quoting Rules


• Perl quoting rules are like Shell quoting rules.
• Single quoted strings are printed literally.
• In double quoted strings the $ and @ and escape sequences are expanded.
• OS commands placed within back quotes are executed, but unlike the shell,
command substitution will not work if the command is enclosed within double
quotes.
• Perl provides an alternate form of quoting: the q, qq, qx and qw.
constructs. The string is enclosed in forward slashes, but alternate delimiters
can be used.
• The delimiters can be matched pairs of characters, such as { }, [ ], ( ).

The q represents single quotes.


The qq represents double quotes.

Basic Perl © 2006 Learning Enterprises, Inc.


16 Module 1

The qx represents back quotes. (See command substitution)


The qw contains a list of array elements (See arrays.)

Example 1.11
(The Script )
#!/usr/bin/perl
1 print ’She cried, ”I can\’t help you!”’,“\n”; # Clumsy
2 print qq/She cried, "I can’t help you!"\n/; # qq for double quotes
3 print qq/I need $5.00\n/; # Really need single quotes for a literal dollar sign to
# print
4 print q/I need $5.00\n/; # What about backslash interpretation?
print ”\n”;
5 print q/I need $5.00/,”\n”;
6 print q!I need $5.00!,”\n”;
7 print ”The present working directory is ”, ‘pwd‘;
8 print qq/Today is /, qx/date/;
9 print ”The hour is ”, qx{date +%H};
10print qq/Hello.\n/;

(The Output )
1 She cried, “I can’t help you!”
2 She cried, “I can’t help you!”
3 I need .00
4 I need $5.00\n
5 I need $5.00
6 I need $5.00
7 The present working directory is /home/jody/ellie/perl
8 Today is Fri Apr 20 17:05:37 PDT 2008
9 The hour is 17
10Hello.

Basic Perl © 2006 Learning Enterprises, Inc.


Getting with it Syntactically 17

1.9 Here Documents


• The Perl here document is like the Shell here document.
• A line oriented form of quoting, requiring << to start the document.
• The << is followed by an initial terminating string. There can be no spaces
after the <<.
• If the terminating string is not quoted or double quoted, variable expansion
is performed. Think of the whole block of text following the <<string as
enclosed in double quotes.
• If the terminating string is single quoted, variable expansion is not per-
formed.
• Each line of text is inserted between the first and last terminating string.
• The final terminating string must be on a line by itself, with no surrounding
white space.
• Perl does not perform command substitution ( back quotes ) in the text of
a here document.
• Perl does allow you to execute system commands in the here document if the
terminator is enclosed in back quotes.
• Used extensively in CGI scripts to embed HTML tags.

Basic Perl © 2006 Learning Enterprises, Inc.


18 Module 1

Example 1.12
( The Script )
#!/usr/bin/perl
1 $name="Ellie";
2 print <<EOF; # The following text is treated as if surrounded by double quotes
3 \t\tHello there $name.
4 How are you doing today?
5 \UThere isn't much going on here\n.
6 EOF

7 print <<‘FINIS’; # The following text is treated as if surrounded by single quotes


8 \t\tHello there $name.
How are you doing today?
9 \UThere isn't much going on here.
10 FINIS

11 print << x 4; # prints the line 4 times. Text must end in a blank line.
12Christmas is coming!

( Output )
3 Hello there Ellie.
4 How are you doing today?
5 THERE ISN'T MUCH GOING ON HERE.

8 \t\tHello there $name.


How are you doing today?
\UThere isn't much going on here.
12 Christmas is coming!
Christmas is coming!
Christmas is coming!
Christmas is coming!

Basic Perl © 2006 Learning Enterprises, Inc.


Getting with it Syntactically 19

Example 1.13
#!/bin/perl
# The HTML tags are embedded in the here document to avoid using
# multiple print statements
1 print <<EOF; # here document in a CGI script
2 Content-type: text/html

3 <HTML><HEAD><TITLE>Town Crier</TITLE></HEAD>
4 <H1><CENTER>Hear ye, hear ye, Sir Richard cometh!!</CENTER></H1>
5 </HTML>
6 EOF

CGI Perl Script--Output from Example 1.21

Basic Perl © 2006 Learning Enterprises, Inc.


20 Module 1

Exercise 1
Getting with it Syntactically
1. At the command line prompt, write a Perl statement that will print:

Hello world!!
Welcome to Perl Programming.

2. Execute a Perl command that will display the version and patch informa-
tion of the Perl distribution you are currently using.

3. Write a Perl script called ”literals.plx” that will print the following (See
next page):
Note: The words PERL SCRIPT and NUMBER are capitalized by using
string literal escape sequences.

What command–line option would you use to check the syntax of your
script?

$ chmod +x literals.plx
$ literals
Today is Wed Oct 18 12:58:04 PDT 2007
The name of this PERL SCRIPT is literals.
Hello. The number we will examine is 125.5.
The NUMBER in decimal is 125.
The following number is taking up 20 spaces and is right justified.
| 125|
The number in hex is 7d
The number in octal is 175
The number in scientific notation is 1.255000e+02
The unformatted number is 125.500000
The formatted number is 125.50
My boss just said, ”Can’t you loan me $12.50 for my lunch?”
I flatly said, ”No way!”.
Good–bye (Makes a beep sound)

Basic Perl © 2006 Learning Enterprises, Inc.


Getting with it Syntactically 21

4. Add to your literals script a here document to print:

Life is good with Perl.


I have just completed my first exercise!

Basic Perl © 2006 Learning Enterprises, Inc.


22 Module 1

Basic Perl © 2006 Learning Enterprises, Inc.


The Funny Characters 23

Module 2
The Funny Characters
2.1 Variables
• Scalars
• Arrays
• Associative Arrays

• Perl variables are identified by the “funny characters” that precede


them.
• Scalar variables are preceded by a $.
• Array variables are preceded by an @.
• Associative array variables, called hashes, are preceded by a %.

2.1 Naming Conventions


• Variables do not have to be declared before being used.
• Variable names consist of any number of letters ( an underscore counts
as a letter) and/or digits.

2.2 Scope and Package

• Perl programs are internally compiled into a package, which provides a


separate name space for variables.
• The default package is called main and all variables are global within
the main package.

Perl Programming Copyright2008, Learning Enterprise, Inc.


24 Module 2

Package main
scalar array hash

$department @department %department


$department[0] $department{’Ed’}

S e pa r a t e N a m e s pa c e s f o r Var i a b l e s

Example 2.1
(The Script)
#!/usr/bin/perl
1 $salary=50000; # Scalar assignment
2 @months=qw(Mar Apr May); # Array
3 %states=( # Associative array assignment in Perl 5
4 ”CA” => ”California”,
5 ”ME” => ”Maine”,
6 ”MT” => ”Montana”,
);
7 print ”$salary\n”;
8 print ”@months\n”;
9 print %states, ”\n”;
10print ”\n\n$months[0] and $months[1]\n”;
11print ”$states{’CA’} and $states{’MT’}\n”;
print ”\n”;
12print $x + 3, ”\n”; # Context is numeric; initial value is 0
print ”\n”;
13print ”***$name***\n”; # Context is string; initial value is null
(The Output)

7 50000
8 Mar Apr May
9 MTMontanaMEMaineCACalifornia

10 Mar and Apr

Perl Programming Copyright 2008, Learning Enterprises, Inc.


The Funny Characters 25

11 California and Montana

12 3

13 ******

Perl Programming Copyright2008, Learning Enterprise, Inc.


26 Module 2

2.3 Scalars
• A scalar variable holds a single value and is preceded by a $ (dollar sign).
• The scalar holds a string or number value.
• The chop function chops off the last character of a scalar variable.
• The Perl5 chomp function chops off the character that is designated as the
end of line character, a newline by default. The special Perl variable, $/,
holds the newline value.

2.4 Assigning a value to a Scalar Variable


Example 2.2
(The Script)
1 #!/usr/bin/perl
2 $num = 5;
3 $name = “John Smith\n”;
4 $money = 125.75;
5 $now = ‘date‘;

6 print “$num\n”;
7 print $name;
8 chomp $name; # removes the newline
9 print “I need \$$money\n”;
10print qq/$name gave me \$$money.\n/;
11print qq/The time is $now/;

(The Output)
6 5
7 John Smith
9 I need $125.75
10 John Smith gave me $125.75.
11 The time is Tue Sep 10 12:34:41 PDT 2005

Perl Programming Copyright 2008, Learning Enterprises, Inc.


The Funny Characters 27

2.5 The $_ scalar variable


• The $_ scalar holds the current line just read and is the default argument for
the print function.
• The $_ is used as the default pattern space for searches.

Example 2.3
1 $_ = "Mary Jones";
2 print; # same as print "$_";

(Output)
Mary Jones

2.5.1 Looping Through a File From Within A Script


• Normally you will not be executing Perl from the command line. If you
want to explicitly loop through a file from within your script, you can either
open up the file within your script or get the filename from the command
line.
• We’ll be discussing the ”open” function in Module 6. For now, we’ll get
the filename from the command line and use a while loop to loop through
the file a line at a time.
• When the empty angle brackets are used (called a null filehandle), Perl
looks for the file at the command line. The file will be opened and each line
read, one line at a time, until the end of file is reached.
• By default, each time a line is read, it is stored in the $_ variable. If an
argument is not provided, Perl reads from stdin.

Example 2.4
(The Script)
#!/home/perl/perl
# Program: loop.file
open(FH, "empnames.txt") ;
1 while(<FH>){ # Each line is read from the file, one at a time, and stored in $_
2 print;
}

Perl Programming Copyright2008, Learning Enterprise, Inc.


28 Module 2

(The Command line)


% loop.file
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

2.6 Arrays
• Arrays are named lists; lists are an ordered sequence of scalars.
• The name of the array starts with a @ sign.
• If the array is initialized, the elements are enclosed in parentheses and each
element is separated by a comma.
• Lists are parenthesized due to the lower precedence of the comma opera-
tor over the assignment operator.
• Subscripts start at zero. $array[0] is the first element of @array. A neg-
ative subscript starts from the end of the array; e.g. $array[-1] is the last ele-
ment and $array[-2] is the last element.
• Elements in an array are simply scalars, and must be preceded with a $
sign.
• The .. operator, the range operator, returns an array of values starting from
the left value to the right value in increments of one.
• If an array is assigned to a scalar, the value of the scalar is the number
of elements in the array. If the array is prefixed with $#, the resulting value
is the number of the last subscript.
• An array without a name is called an anonymous array.
(Perl5)
• The qw construct allows you to list array elements as singly quoted words.

Perl Programming Copyright 2008, Learning Enterprises, Inc.


The Funny Characters 29

Example 2.5
( The Script )
#!/usr/bin/perl
1 @names=(‘John’, ‘Joe’, ‘Jake’);
2 print @names, “\n”; # prints without the separator ( See join )
3 print “Hi $names[0], $names[1], and $names[2]!\n”;

4 $number=@names; #The scalar, $number, is assigned the number of


# elements in the array
5 print “There are $number elements in the \@names array.\n”;
6 print ”The last element of the array is $names[– 1].\n”;
# Remember, subscript starts at zero!!
7 print ”The number of the last subscript in the array is $#names.\n”;
8 @fruit=qw/apples pears peaches plums/;
9 print ”The first element in the \@fruit array is $fruit[0]; the second element is
$fruit[1].\n”;
10print “Starting at the end of the array; @fruit[-1, -3]\n”;

( The Output )
2 JohnJoeJake
3 Hi John, Joe, and Jake!
5 There are 3 elements in the @names array.
6 The last element of the array is Jake.
7 The number of the last subscript in the array is 2.
9 The first element of the @fruit array is apples; the second element is pears.
10 Starting at the end of the array: plums pears

Perl Programming Copyright2008, Learning Enterprise, Inc.


30 Module 2

2.7 Array slices


• When the elements of one array are assigned the values from another
array, the resulting array is called an array slice.
• If the array on the right hand side of the assignment operator is larger than
the array on the left hand side, the unused values are discarded. If it is
smaller, the values assigned are undefined.

Example 2.6
( The Script )
#!/usr/bin/perl
1 @names=(’Tom’, ’Dick’, ’Harry’, ’Pete’);
2 @pal=@names[1,2,3]; # slice
3 print ”@pal\n\n”;

4 ($friend[0], $friend[1], $friend[2])=@names; # slice


5 print ”@friend\n”

( The Output )
3 Dick Harry Pete
5 Tom Dick Harry

Perl Programming Copyright 2008, Learning Enterprises, Inc.


The Funny Characters 31

2.8 Some Array Functions


• There are a number of built-in array functions to make it easy to manip-
ulate arrays.
• A complete list of array functions can be found in "Perl by Example" or
looking in the Perl man pages.

2.8.1 The pop Function

• The pop function pops off and returns the last element of an array.

Format:
pop(ARRAY)
pop ARRAY

Example 2.7
(In Script)
#!/usr//bin/perl
# Script: pop_function
1 @names=(“Bob”, “Dan”, “Tom”, “Guy”);
2 print "@names\n”;
3 print pop(@names); #pops off last element of the array
4 print ”\n@names\n”;

(The Output)
2 Bob Dan Tom Guy
3 Guy
4 Bob Dan Tom

Before After

Bob Dan Tom Guy pop off the end Bob Dan Tom

Perl Programming Copyright2008, Learning Enterprise, Inc.


32 Module 2

2.8.2 The push Function

• The push function pushes values onto the end of an array, increasing the
length of the array.

Format:
push(ARRAY, LIST)

Example 2.8
(In Script)
#!/usr//bin/perl
# Script: push_function
1 @ names=(“Bob”, “Dan”, “Tom”, “Guy”);
2 push(@names, Jim, Joseph, Archie);
3 print “@names \n”;

(The Output)
3 Bob Dan Tom Guy Jim Joseph Archie

Before After

push on
Bob Dan Tom Guy
to the
Bob Dan Tom Guy Jim Joseph Archie
end

2.8.3 The shift Function

• The shift function shifts off and returns the first element of an array,
decreasing the size of the array by one element.
If ARRAY is omitted, then the ARGV array is shifted, and if in a subroutine,
the @_ array is shifted.

Format:
shift(ARRAY)
shift ARRAY
shift

Perl Programming Copyright 2008, Learning Enterprises, Inc.


The Funny Characters 33

Example 2.9
(The Script)
#!/usr/bin/perl
# Script: shift_function
1 @names=(“Bob”, “Dan”, “Tom”, “Guy”);
2 shift @names; # shifts the @names array one to the left
3 print "@names\n”;
4 $num=1;

(The Output)
3 DanTom Guy

Before After

Bob Dan Tom Guy shift off the beginning Dan Tom Guy

2.8.4 The unshift Function

• The unshift function prepends LIST to the the front of the


array.

Format:
unshift(ARRAY, LIST)

Example 2.10
(In Script)
# Script: unshift_function
1 @names=( Jody, Bert, Tom ) ;
2 unshift(@names, Liz, Daniel);
3 print “@names\n”;

(The Output)
3 Liz Daniel Jody Bert Tom

Before After

Jody Bert Tom prepend to the beginning Liz Daniel Jody Bert Tom

Perl Programming Copyright2008, Learning Enterprise, Inc.


34 Module 2

2.8.5 The split Function


(See Array Functions)
• The split function splits up a scalar string by some delimiter ( whitespace
by default ) and returns an array. The first argument is the delimiter, the
second is the string to be split.
• When processing files, as you would with awk, the Perl split function is
used to create fields. If a string is not supplied, the $_ variable is split.
• If the delimiter is a quoted space, ’ ’, Perl splits on contiguous spaces ( like
awk), ignoring leading white space. If the expression. / / is used, any leading
white space is treated as a null initial field.
• The return value of many of Perl’s system interface functions is an array.

Example 2.11
(The Script)
#!/usr/bin/perl
1 $string=“Dane Leo Starkey”;
2 @names=split(‘ ’,$string);
3 print “The first name is $names[0].\n”;
4 print “The second name is $names[1].\n”;

(The Output)
3 The first name is Dane.
4 The second name is Leo.
news
ingres
audit

Example 2.12
The list returned by split in this example has no name. It is called an anonymous
list. Because each of the items in the list are named variables, it is easier to read
and manipulate the script’s data.

(The File)
$ cat datebook
Betty Boop:245–836–8357:635 Cutesy Lane, Hollywood, CA 91464:6/23/
23:14500
Igor Chevsky:385–375–8395:3567 Populus Place, Caldwell, NJ 23875:6/18/
68:23400
Norma Corder:397–857–2735:74 Pine Street, Dearborn, MI 23874:3/28/
45:245700
Jennifer Cowan:548–834–2348:583 Laurel Ave., Kingsville, TX 83745:10/1/
35:58900

Perl Programming Copyright 2008, Learning Enterprises, Inc.


The Funny Characters 35

Fred Fardbarkle:674–843–1385:20 Park Lane, Deluth, MN 23850:4/12/23:78900

Example 2.13
(The Script)
#!/usr/bin/perl
# This script loops through a file; each line is split using the colon as a separator.
# If the second argument to split is missing, the default is $_.

open(FH, "datebook.master");
1 while(<FH>) {
2 ($name,$phone,$address,$bd,$sal)=split(":") ;
3 print ”$name $phone\n”;
}
close(FH)

(The Output)
3 Betty Boop 245–836–8357
Igor Chevsky 385–375–8395
Norma Corder 397–857–2735
Jennifer Cowan 548–834–2348
Fred Fardbarkle 674–843–1385

Perl Programming Copyright2008, Learning Enterprise, Inc.


36 Module 2

2.8.6 The join Function

• The join function joins the elements of an array into a single string and
separates each element of the array with a delimiter––opposite of split.
Often used after the split function has broken a string into array elements.

Format:
join(EXPR, LIST)

EXPR is the value of the delimiter that will separate the array elements.
LIST consists of the array elements.

Example 2.14
#!/usr/bin/perl
Script: join_function
1 $string= “Joe Blow:11/12/86:10 Main St.:Boston, MA:02530”;
2 ($name, $birth, $address)=split(":", $string);
3 print $name, “\n”;
4 print $birth,“\n”;
5 print $address,“\n”;
6 print join(“:”, $name, $birth, $address ), “\n”;

(The Output)
3 Joe Blow
4 11/12/86
5 10 Main St.
6 Joe Blow:11/12/86:10 Main St.

Perl Programming Copyright 2008, Learning Enterprises, Inc.


The Funny Characters 37

2.8.7 The reverse Function

• The reverse function reverses the elements in an array, so that if it was


descending, now it is ascending, etc.

Format:
reverse(LIST)
reverse LIST

Example 2.15
(In Script)
#!/usr/bin/perl
#Script: reverse_function
1 @names=(“Bob”, “Dan”, “Tom”, “Guy”);
2 print “@names \n”;
3 @reversed=reverse(@names);
4 print join(“ ”, @reversed,“\n”);

(The Output)
2 Bob Dan Tom Guy
4 Guy Tom Dan Bob

Perl Programming Copyright2008, Learning Enterprise, Inc.


38 Module 2

2.8.8 The splice Function

• The splice function removes the elements in an array starting at OFF-


SET (the index value), followed by the LENGTH (number of elements to
remove), and optionally replaces them with a new LIST of items. If OFF-
SET is negative, then it starts from the end of the array. If LENGTH is omit-
ted, everything is removed from that element to the end of the array.

Format:
splice ARRAY,OFFSET,LENGTH,LIST
splice ARRAY,OFFSET,LENGTH
splice ARRAY,OFFSET
splice ARRAY

@LIST = splice(@ARRAY, OFFSET, LENGTH, @REPLACE_WITH);

Example 2.16
1 @colors=qw(red green blue yellow);
2 print "Array was: @colors.\n";
3 @return_value=splice(@colors,1,1);
4 print "New array: @colors.\n";
5 print "What was removed: @return_value.\n";

6 @colors=qw(red green blue yellow);


7 print "Array was: @colors.\n";
8 splice(@colors,2,1,"purple");
9 print "New array: @colors.\n";

(Output)
2 Array was: red green blue yellow.
4 New array: red blue yellow.
5 What was removed: green.
7 Array was: red blue yellow.
9 New array: red blue purple.

Perl Programming Copyright 2008, Learning Enterprises, Inc.


The Funny Characters 39

2.9 Associative Arrays (Hashes)


• Associative arrays use strings for subscripts.
• Associates a pair of strings with another set of strings, numbers, or Bool-
eans.
• The first pair of strings is called the key and the second pair it is associated
with is called the value.
• The subscript is the key value enclosed in curly braces.
• The array must be defined before the elements can be referenced.
• Perl 4 used the comma to separate the key and value items; Perl5 uses
=> (digraph symbol). The comma still works in Perl5.
• Associative arrays can be nested. (Perl5)
• The built-in keys function returns an array of the keys from an associative
array.
• The built-in values function returns an array of the values from an asso-
ciative array.

Example 2.17
(In Script )
1 %department = (
2 ’Eng’ => ’Engineering’, # Eng is the key, Engineering is the value
3 ’M’ => ’Math’,
4 ’S’ => ’Science’,
5 ’CS’ => ’Computer Science’,
6 ’Ed’ => ’Education’,
7 );
8 $department = $department{“M”};
9 $school = $department{“Ed”};
10print “I work in the $department section\n” ;
11 print “Funds in the $school department are being cut.\n”;
12print qq/I’m currently enrolled a $department{CS} course.\n/;
13print qq/The department associative array looks like this:\n/;
14print %department, “\n”;

( The Output )
10 I work in the Math section
11 Funds in the Education department are being cut.
12 I’m currently enrolled a Computer Science course.
13 The department associative array looks like this:
14 EdEducationEngEngineeringSScienceMMathCSComputer Science

Perl Programming Copyright2008, Learning Enterprise, Inc.


40 Module 2

2.9.1 Some Built-in Hash Functions

Example 2.18
(The Script)
#!/usr/bin/perl
# Script using built-in functions to get the keys and values from a hash
1 %department = (
Eng => ’Engineering’, # Eng is the key, Engineering is the value
M => ’Math’,
S => ’Science’,
CS => ’Computer Science’,
Ed => ’Education’,
);
2 @keylist = keys(%department); # The keys function returns a list of hash keys
3 print "@keylist\n";

4 @valuelist = values(%department); # The values function returns a list of


# of hash values
5 print "@valuelist\n";

6 while( ($key, $value) = each(%department)){


7 print "$key - $value\n";
}

(The Output)
3 Ed Eng S M CS
5 Education Engineering Science Math Computer Science
7 Ed - Education
Eng - Engineering
S - Science
M - Math
CS - Computer Science

Perl Programming Copyright 2008, Learning Enterprises, Inc.


The Funny Characters 41

2.10 Reading From STDIN


• The Perl filehandles STDIN, STDOUT, and STDERR are predefined.
• The special filehandle ARGV allows you to use file names as command
line arguments. (See More Arrays)
• For Unix users, these are the same stdin, stdout, and stderr used by the
shell and defined in /usr/include/stdio.h.
• Perl lets you create your own filehandles with the open function.

2.11 <STDIN> Standard Input


• Normally comes from the keyboard
• The angle brackets enclose the file handle to indicate that the next line of
input is to be read from standard input, until the carriage return.
• Angle brackets are used only to indicate a read operation.
• The value returned includes the newline and is true, until EOF is reached.
• Normally the value returned is assigned to a variable. If the variable is a
scalar, the next line of input is read from STDIN; if the variable is an array,
all the rest of the input lines are read until EOF; this is probably NOT what
you want; use ^d (control d) for EOF.
• The chomp function removes the trailing newline.
• Perl performs filename globbing within angle brackets.
• The null filehandle <> evaluates command line arguments if there are any;
otherwise takes the next line from standard input to be processed.

2.11.1 Assigning input to a scalar

Example 2.19
(In Script)
#!/usr/bin/perl
1 print “What is your name? ”;
2 $name = <STDIN> ; #set $name to the next line of input; can use <>
3 chomp($name); # Remove the newline.
4 print “$name, how are you?\n”;

(The Output)
1 What is your name? Santa Clause
4 Santa Clause, how are you?

Perl Programming Copyright2008, Learning Enterprise, Inc.


42 Module 2

2.11.2 Assigning Input to an Array

• When reading input from STDIN, if the context is array, each line is read
with its newline and the whole line is treated as a single list item (single ele-
ment of the array).
• So that the program will stop accepting input, the user must press Ctrl-d
(^D).

Example 2.20
(The Script)
1 print ”Tell me everything about yourself.\n”;
2 @all = <STDIN>; # First line of input is assigned to $all[0], etc.
3 print @all;
4 print "$all[0]\n";

(The Output)
1 Tell me everything about yourself.
2 O.K. Let’s see. I was born a long time ago.
I was part of the hippy generation.
I have four children and two dogs.
I’m getting sick of talking about myself
^D (Ctrl d)
3 O.K. Let’s see. I was born a long time ago.
I was part of the hippy generation.
I have four children and two dogs.
I’m getting sick of talking about myself
4 O.K. Let’s see. I was born a long time ago.

2.11.3 Assigning Input to an Associative Array

Example 2.21
(The Script)
#!/usr/bin/perl
1 $course_number = 101;
2 print ”What is the name of course 101? ”;
3 chomp($course{$course_number} = <STDIN>);
4 print ”The course is $course{$course_number}.”;

(The Output)
2 What is the name of course 101? Intro Computer Science <-- user input
4 The course is Intro Computer Science.

Perl Programming Copyright 2008, Learning Enterprises, Inc.


The Funny Characters 43

2.12 Special Hashes

2.12.1 The %ENV Hash

• The %ENV hash contains the environment variables handed to Perl from
the parent process, e.g., a shell or a Web server.
• The key is the name of the environment variable, and the value is what
was assigned to it. If you change the value of %ENV, you will alter the envi-
ronment for your Perl script and any processes spawned from it, but not the
parent process. Environment variables play a significant roll in CGI Perl
scripts.

Example 2.22
(In Script)
#!/usr/bin/perl
1 foreach $key (keys(%ENV){
2 print "$key\n"; }
3 print "\nYour login name $ENV{'LOGNAME'}\n";
4 $pwd=$ENV{'PWD'};
5 print "\n", $pwd, "\n";
}
(Output)
OPENWINHOME
MANPATH
FONTPATH
LOGNAME
USER
TERMCAP
TERM
SHELL
PWD
HOME

Perl Programming Copyright2008, Learning Enterprise, Inc.


44 Module 2

2.13 The %SIG Hash


• Signals allow the manipulation of a process.

• There are two general types of signals: those that cause termination of a
process and those that do not.

• Signals which cause termination of a program might result from an


irrecoverable error or might be the result of a user at a terminal
typing the `interrupt' character.

• Most signals result in the termination of the process receiving them if


no action is taken; some signals instead cause the process receiving them to
be stopped, or are simply discarded if the process has not requested other-
wise.

• Except for the SIGKILL and SIGSTOP signals, signals can be caught,
ignored, or generate an interrupt. These signals are defined in the file <sig-
nal.h>.

• The %SIG hash allows you to set signal handlers for signals. If, for exam-
ple, you press <Ctrl>-C when your program is running, that is a signal, iden-
tified by the name, SIGINT. (See UNIX manual pages for a complete list of
signals.)

• The default action of SIGINT is to interrupt your process. The signal han-
dler is a subroutine that is automatically called when a signal is sent to the
process. Normally, the handler is used to perform a clean-up operation or to
check some flag value before the script aborts. (All signal handlers are
assumed to be set in the main package.)

• The %SIG array only contains values for signals set within the Perl script.

TABLE 2.1 Some Signals


No Name Default Action Description
1 SIGHUP terminate process terminal line hangup
2 SIGINT terminate process interrupt program
3 SIGQUIT create core image quit program
4 SIGILL create core image illegal instruction
5 SIGTRAP create core image trace trap
6 SIGABRT create core image abort program (formerly SIGIOT)

Perl Programming Copyright 2008, Learning Enterprises, Inc.


The Funny Characters 45

7 SIGEMT create core image emulate instruction executed


8 SIGFPE create core image floating-point exception
9 SIGKILL terminate process kill program
10 SIGBUS create core image bus error
11 SIGSEGV create core image segmentation violation
12 SIGSYS create core image non-existent system call invoked
13 SIGPIPE terminate process write on a pipe with no reader
14 SIGALRM terminate process real-time timer expired
15 SIGTERM terminate process software termination signal
16 SIGURG discard signal urgent condition present on
socket
17 SIGSTOP stop process stop (cannot be caught or

Example 2.23
(In Script)
#!/usr/bin/perl
1 sub handler{
2 local($sig) = @_; # First argument is signal name
3 print "Caught SIG$sig -- shutting down\n";
exit(0);
}
4 $SIG{'INT'} = 'handler'; # Catch <Ctrl>-c
print "Here I am!\n";
5 sleep(10);
6 $SIG{'INT'}='DEFAULT';
7 $SIG{'INT'}='IGNORE'; < Program continues here >

Perl Programming Copyright2008, Learning Enterprise, Inc.


46 Module 2

Exercise 2
The Funny Characters

1. Write a script called foods that will create a list of your favorite five
foods. The list of foods will be stored in a scalar, each food separated by a
comma. Split the scalar and create an array.

a. Print the array.


b. Print the last element of the array.
c. Print the number of elements in the array.
d. Create an array slice from three elements of the food array and print
the values.
e. Push three new elements onto the end of the array and print the array.
f. Remove the first element of the array.
g. Reverse the array.

2. Write a script called “elective” that will contain a hash (associative array).
a.The keys will be code numbers––2CPR2B, 1UNX1B, 3SH414,
4PL400.
b.The values will be course names, “C Language”, “Intro to UNIX”,
“Shell Programming”, “Perl Programming”.
c. Print the entire hash.
d. Ask the user to type the code number for the course he plans
to take this semester and print a line resembling the following:
You will be taking Shell Programming this semester.

3. Modify your ’elective’ script to produce output resembling that seen


below. The user will be asked to enter registration information and to select
an EDP number from a menu. The course name will be printed. It doesn’t
matter if the user types in the EDP number with upper or lower case letters.
A message will confirm the user’s address and thank him for enrolling.

Output should resemble the following:

REGISTRATION INFORMATION FOR SPRING QUARTER


Today’s date is Thu Apr 19 17:40:19 PDT 2008

Perl Programming Copyright 2008, Learning Enterprises, Inc.


The Funny Characters 47

Please enter the following information:


Your full name: Fred Z. Stachelin
What is your Social Security Number (xxx–xx–xxxx): 004–34–1234
Your address:
Street: 1424 Hobart St.
City, State, Zip: chico, ca 95926

”EDP” NUMBERS AND ELECTIVES:

1UNX1B | Intro to UNIX


––––––––––––––––––––––––––––––
4PL400 | Perl Programming
––––––––––––––––––––––––––––––
2CPR2B | C Programming
––––––––––––––––––––––––––––––
3SH414 | Shell Programming
––––––––––––––––––––––––––––––

What is the EDP number of the course you wish to take? 4pl400
The course you will be taking is ”Perl Programming”.

Registration confirmation will be sent to your address at:


1424 HOBART ST.
CHICO, CA 95926
Thank you, Fred, for enrolling.

Perl Programming Copyright2008, Learning Enterprise, Inc.


48 Module 2

Perl Programming Copyright 2008, Learning Enterprises, Inc.


Operator, operator... 49

Module 3
Operator, operator...
3.1 Operators
3.2 Precedence and Associativity
• When an expression contains a number of operators and operands, and the
result of the operation is potentially ambiguous, the order of precedence and
associativity tells you how the compiler evaluates such an expression.
• Precedence refers to the way in which the operator binds to its operand.
The multiplication operator binds more tightly to its operands than the addi-
tion operator so it is of higher precedence, whereas the assignment operators
are low in precedence and thus bind loosely to their operand. 1
• Parentheses are of the highest precedence and are used to control the way
an expression is evaluated. When parentheses are nested, the expression
contained within the innermost set of parentheses is evaluated first.
• Associativity refers to the order in which an operator evaluates its oper-
ands, left to right, in no specified order, or right to left.

Example 3.1
(The Script)
1 $x = 5 + 4 * 12 / 4;
2 print "The result is $x\n";
3 $x = ( 5 + 4 ) * ( 12 / 4 );
4 print "The result is $x\n";

Output
2 The result is 17
4 The result is 27

1. Another way to remember precedence: "Please excuse my dear Aunt Sally"

Basic Perl © 2006 Learning Enterprises, Inc.


50 Module 3

Precedence and Associativity


Operator DescriptionAssociativity
() [ ] { } Function call, array subscriptsLeft to right
++ -- Auto increment, decrementNone
!~- Logical not, bitwise not, unary minusRight to left
** ExponentiationRight to left
=~ !~ Match and not matchLeft to right
* / % x Multiply, divide, modulus, string repetitionLeft to right
+ - . Add, subtract, string concatenationLeft to right
. << >> Bitwise left shift, right shiftLeft to right
-r -w -x -o , etc. File test operatorsNone
unary operators
< <= > >= lt le gt ge Numeric and string tests, e.g., less than,None
greater than, etc.
== != <=> eq ne cmpNumeric and string tests, e.g., equal to,None
not equal to, etc.
& Bitwise andLeft to right
| ^ Bitwise or, exclusive orLeft to right
&& Logical andLeft to right
|| Logical orLeft to right
.. Range operatorNone
?: Ternary, conditionalRight to left
= += -= *= /= %= AssignmentRight to left
, ( comma ) => Evaluate left operand, discard it,Left to right
and evaluate right operand
not and or xor Logical and, or, and exclusive or Left to right

3.2.1 String or Number?


• Numbers are either integers or floating point numbers.
• If using a numeric operator, Perl expects numeric operands. If either of
the operands is a string, it will be converted to a number, if possible. If the
string cannot be converted to a number, then it will be converted to 0. Like-
wise if the operator is a string operator, the operands will be treated as
strings.
TABLE 3.1 How Strings are Converted to Numbers
String converts to Number
"123 go!" 123
"hi there" 0
"4e3" 4000
"-6**3xyz" -6
" .456!!" 0.456
"x.1234" 0
"0xf" 0
"08abc" 8

Perl Programming Copyright 2008, Learning Enterprises, Inc.


Operator, operator... 51

3.3 Arithmetic Operators

Operator/Operands Function

$x + $y Addition
$x – $y Subtraction
$x * $y Multiplication
$x / $y Division
$x % $y Modulus
$x ** $y Exponentiation

Example 3.2
(The Script)
1 printf "%d\n", 4 * 5 / 2;
2 printf "%d\n", 5 ** 3;
3 printf "%d\n", 5 + 4 - 2 * 10;
4 printf "%d\n", (5 + 4 - 2 ) * 10;
5 printf "%d\n", 11 % 2;

Output
1 10
2 125
3 -11
4 70
5 1

3.4 Assignment Operators


• The short circuit assignment operators allow you to perform an arithmetic
or string operation by combining an assignment operator with an arithmetic
or string operator. For example, $x = $x + 1 can be written: $x+=1.
= **= <<=
+= *= >>=
–= /= &=
.= x= ^=
%= |=

Example 3.3
(The Script)

Basic Perl © 2006 Learning Enterprises, Inc.


52 Module 3

1 $name="Dan";
2 $line=”*”;
3 $x=0; # assign 0 to $x
4 $x += 3; # add 3 to $x; same as $x=$x+3
5 print “x=x+3 is $x \n”;

6 $x –= 1; # subtract one from $x


7 print ”x=x–1 is $x\n”;

8 $x **= 2; # square x
9 print ”x squared is $x\n” ; #

10$x %= 3;
11 print ”The remainder of x/3 is $x\n”;

12$name .= “ielle”; # concatenate string “Dan” and “ielle”


13print “$name\n”;

14$line x= 10; # repetition


15print ”$line\n”;

(The Output)
5 x=x+3 is 3
7 x=x–1 is 2
9 x squared is 4
11 The remainder of x/3 is 1
13 Danielle
15 **********

3.5 Relational Operators


• When operands are compared, relational operators are used. The result of
the comparison is either true or false.
• Perl has two classes of relational operators, one set that compares numbers
and another that compares strings.
The expression (5 > 4 > 2) will produce a syntax error because there is no
associativity.

Perl Programming Copyright 2008, Learning Enterprises, Inc.


Operator, operator... 53

3.5.1 Numeric

Operator/Operands Function

$num1 == $num2 $num1 is equal to $num2


$num1 != $num2 $num1 is not equal to $num2
$num1 > $num2 $num1 is greater than $num2
$num1 >= $num2 $num1 is greater than or equal to $num2
$num1 < $num2 $num1 is less than $num2
$num1 <= $num2 $num1 is less than or equal to $num2
$num1 <=> $num2 $num1 is compared to $num2, with signed return if
numbers are not equal. If $num1 is less than $num2
return is –1; if $num2 is less than $num1, return is +1; other-
wise, return is 0.

3.5.2 String

Operator/Operands Function

$str1 eq $str2 $str1 is equal to $str2


$str1 ne $str2 $str1 is not equal to $str2
$str1 ge $str2 $str1 is greater than or equal to $str2
$str1 gt $str2 $str1 is greater than $str2
$str1 lt $str2 $str1 is less than $str2
$str1 le $str2 $str1 is less than or equal to $str2
$str1 cmp $str2 $str1 is compared to $str2, with signed return if strings are
not equal.
-----------------------------------------------------------------------------

Basic Perl © 2006 Learning Enterprises, Inc.


54 Module 3

Numeric. Table contains a list of numeric relational operators.

TABLE 3.2 Relational Operators and Numeric Values


Operator ExampleMeaning
> $x > $y$x is greater than $y
>= $x >= $y$x is greater than or equal to $y
< $x < $y$x is less than $y
<= $x <= $y$x is less than or equal to $y

Example 3.4
(The Script)
$x = 5;
$y = 4;
1 $result = $x > $y;
2 print "$result\n";

3 $result = $x < $y;


4 print $result;

Output
2 1
4 0

String.
• The string relational operators evaluate their operands (strings) by com-
paring the ASCII value of each character in the first string to the correspond-
ing character in the second string. The comparison includes trailing
whitespace.
• If the first string contains a character that is of a higher or lower than
ASCII value than the corresponding character in the second string, the value
one is returned. Otherwise zero is returned.
Table 3.2 contains a list of relational string operators.
TABLE 3.3 Relational Operators and String Values
Operator ExampleMeaning
gt $str1 gt $str2$str1 is greater than $str2
ge $str1 ge $str2$str1 is greater than or equal to $str2
lt $str1 lt $str2$str1 is less than $str2
le $str1 le $str2$str1 is less than or equal to $str2

Perl Programming Copyright 2008, Learning Enterprises, Inc.


Operator, operator... 55

Example 3.5
(The Script)
1 $fruit1 = "pear";
2 $fruit2 = "peaR";
3 $result = $fruit1 gt $fruit2;
4 print "$result\n";

5 $result = $fruit1 lt $fruit2;


6 print "$result\n";

Output
4 1
6 0

3.6 Equality Operators


• The equality operators evaluate numeric operands and string operands (see
Tables 2.3 and 2.4).

Numeric.

• The numeric equality operators evaluate their operands (numbers) by


comparing their numeric values. If the operands are equal, one (true) is
returned; if the operands are not equal, zero (false) is returned.
• The numeric comparison operator evaluates its operands, returning a neg-
ative one (-1) if the first operand is less than the second operand, zero (0) if
the numbers are equal, and one (1) if the first operand is greater than the sec-
ond.
TABLE 3.4 Equality Operators and Numeric Values
Operator ExampleMeaning
== $num1 == $num2$num1 is equal to $num2
!= $num1 != $num2$num1 is not equal to $num2
<=> $num1 <=> $num2$num1 is compared to $num2 with signed return; 1 if $num1 is
greater than $num2, 0 if $num1 is equal to $num2, and -1 if
$num1 is less than $num2

Basic Perl © 2006 Learning Enterprises, Inc.


56 Module 3

Example 3.6
(The Script)
$x = 5;
$y = 4;
1 $result = $x == $y;
2 print "$result\n";

3 $result = $x != $y;
4 print "$result\n";

5 $result = $x <=> $y;


6 print "$result\n";

7 $result = $y <=> $x;


8 print "$result\n";

Output
2 0
4 1
6 1
8 1

String.

• The string equality operators evaluate their operands (strings) by compar-


ing the ASCII value of each character in the first string to the corresponding
character in the second string. The comparison includes trailing whitespace.
• If the first string contains a character that is of a higher ASCII value than
the corresponding character in the second string, the value one is returned.
Otherwise zero is returned.
• The string comparison operator evaluates its operands by comparing the
ASCII value of each character in the first string to the corresponding char-
acter in the second string. If the first string operand is less than the second
operand, negative one (-1) is returned. If the first string is greater than the
second string, one (1) is returned, and if the strings are equal, zero (0) is
returned.
TABLE 3.5 Equality Operators and String Values
Operator Example Meaning
eq $str1 eq $str2 $str1 is equal to $str2
ne $str1 ne $str2 $str1 is not equal to $str2
cmp $str1 cmp $str2 $str1 is compared to $str2, with signed return

Perl Programming Copyright 2008, Learning Enterprises, Inc.


Operator, operator... 57

Example 3.7
(The Script)
$str1 = "A";
$str2 = "C";
1 $result = $str1 eq $str2;
print "$result\n";

2 $result = $str1 ne $str2;


print "$result\n";

3 $result = $str1 cmp $str2;


print "$result\n";
4 $result = $str2 cmp $str1;
print "$result\n";

5 $str1 = "C"; # Now both strings are equal.


6 $result = $str1 cmp $str2;
print "$result\n";

Output
1 0
2 1
3 -1
4 1
6 0

Example 3.8
# Don’t use == when you should use eq!
1 $x = "yes";
2 $y = "no";
print "\nIs yes equal to no? If so, say 1; if not say 'null'.\n";
3 print "The result is: ",$x == $y,"\n"; # should be $x eq $y

Output
3 Is yes equal to no? If so, say 1; if not say 'null'.
The result is: 1

Basic Perl © 2006 Learning Enterprises, Inc.


58 Module 3

3.7 Logical Operators


• The short-circuit operators evaluate their operands, from left to right, test-
ing the truth or falsity of each operand in turn. There is no further evaluation
once a true or false condition is satisfied. The short-circuit operators do not
return 0 (false) or 1 (true), but rather the value of the last operand evaluated.
• These operators are most often used in conditional statements.
• The logical operators can also be represented as and, or, or not, but the pre-
cedence for them is lower. See Precedence and Associativity Table 3.2.

Operator/Operands Function
$num1 && $num2 $num2, if $num1 and $num2 are true.
$num1 || $num2 $num1, if $num1 is true or $num2 if $num2 is true.
! $num1 Not $num1; returns either 1 or the null string..

-----------------------------------------------------------------------------------

Example 3.9
(In Script)
#!/usr/bin/perl
1 # logical operators
2 $num1=50;
3 $num2=100;
4 $num3=0;
5 print $num1 && $num2, ”\n”; # could use $num1 and $num2
6 print $num1 && $num3, ”\n”;
7 print $num1 || $num3, ”\n”; # could use $num1 or $num2
8 print ! $num3, ”\n”; # could use not $num3
9 print !( $num1 && $num2),”\n”;

(The Output)
5 100
6 0
7 50
8 1
9

Perl Programming Copyright 2008, Learning Enterprises, Inc.


Operator, operator... 59

3.8 Autoincrement and Autodecrement Operators


Operator Function

++$x Pre–increment
$x++ Post–increment
––$x Pre–decrement
$x–– Post–decrement

• The autoincrement operator adds one to $x. The autodecrement


operator subtracts one from $x.

• The placement of the operators makes a difference when an assignment is


made to another variable.

Example 3.10
(The Script)
#!/usr/bin/perl
1 $x=5; $y=0;
2 $y=++$x; #add one to $x first; then assign to $y
3 print ”Pre–increment:\n”;
4 print “y is $y\n”;
5 print “x is $x\n”;
6 print “–––––––––––––––––––––––\n”;
7 $x=5;
8 $y=0;
9 print ”Post–increment\n”;
10$y=$x++; # assign value in $x to $y; then add one to $x
11 print “y is $y\n”;
12print “x is $x\n”;

(The Output)
3 Pre–increment:
4 y is 6
5 x is 6
–––––––––––––––––––––––
9 Post–increment
10 y is 5
11 x is 6

Basic Perl © 2006 Learning Enterprises, Inc.


60 Module 3

3.9 String Operators


TABLE 3.6
String Operations
Example Meaning
$str1 . $str2 Concatenate strings $str1 and $str2
$str1 x $num Concatenate $str1, $num times
substr ( $str1, $offset, $len ) Substring of $str1 at $offset for $len bytes
index ( $str1, $str2 ) Byte offset of string $str2 in string $str1
length (EXPR) Returns the length in characters of expression, EXPR
rindex( $str, $substr, POSITION )Returns the position of the last occurrence of $substr in $str.
If the POSITION is specified, start looking there. If POSITION is not
specified, start at the end of the string.
chr(NUMBER) Returns the character represented by that NUMBER in the ASCII
character set. For example, chr(65) is ’A’.
lc($str) Returns a lowercase string.
uc($str) Returns an uppercase string.

Example 3.11
(The Script)
#!/usr/bin/perl
1 $x="pop";
2 $y="corn";
3 $z="*";
4 print $z x 10, "\n"; # print 10 stars
5 print $x . $y, "\n"; # concatenate "pop" and "corn"
6 print $z x 10, "\n"; # print 10 stars
7 print (($x . $y ." ") x 5 ); # concatenate "pop" and "corn" and print 5 times
8 print "\n";
9 print uc($x . $y), "!\n"; #convert string to uppercase

Output
4 **********
5 popcorn
6 **********
7 popcorn popcorn popcorn popcorn popcorn
9 POPCORN!

Perl Programming Copyright 2008, Learning Enterprises, Inc.


Operator, operator... 61

Example 3.12
(The Script)
#!/usr/bin/perl
1 $line=“Happy New Year”;
2 print substr($line, 6, 3),”\n”; # offset starts at zero
3 print index($line, “Year”),”\n”;
4 print substr($line, index($line, “Year”)),”\n”;
5 substr($line, 0, 0)=“Fred, ”;
6 print $line,”\n”;
7 substr($line, 0, 1)=“Ethel”;
8 print $line,“\n”;
9 print substr($line, –4);
10print uc ”have a wonderful year!!\n”;
11$string="I'll eat a tomato tomorrow.\n";
12 print rindex($string, tom), "\n";

(The Output)
2 New
3 10
4 Year
6 Fred, Happy New Year
8 Ethelred, Happy New Year
9 you!
10 HAVE A WONDERFUL YEAR!!
12 18

Basic Perl © 2006 Learning Enterprises, Inc.


62 Module 3

3.10 Range Operator

100 .. 200 A range operator, starting with 100 and going to 200, incrementing
by 1; e.g. 100, 101, 102 ... 199, 200

Example 3.13

1 foreach $num(1..10){print “$num ”;}print “\n”’


1 2 3 4 5 6 7 8 9 10

2 @a=(’A’..’Z’) ; print ”@a\n”’


ABCDEFGHIJKLMNOPQRSTUVWXYZ

3 @a=(’a’..’z’, ’A’..’Z’) ; print ”@a\n”’


abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP
QRSTUVWXYZ

4 @a=( –5 .. 20 ) ; print ”@a\n”


–5 –4 –3 –2 –1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

3.11 Generating Random Numbers

3.11.1 The rand/srand function

• The rand function returns a random fractional number between 0 and 1.


• If EXPR has a positive value, rand returns a fractional number between 0
and EXPR.
• The srand function sets the random number seed for the rand function. If
EXPR is omitted, the return value of the time functions used as the seed. It
is no longer necessary to seed the rand() function.

Format:
rand(EXPR)
rand EXPR
rand

srand(EXPR)
srand EXPR

Perl Programming Copyright 2008, Learning Enterprises, Inc.


Operator, operator... 63

Example 3.14
(The Script)
#!/usr/bin/perl
1 $num=10;
2 srand(time|$$); # seed rand with the time or’ed to the pid of this process
3 while($num){ # srand not necessary in versions 5.004 and above
4 $lotto = int(rand(10)) + 1; # returns a random number between 1 and 10
5 print ”The random number is $lotto\n”;
sleep 3;
$num––;
}
(The Output)
The random number is 5
The random number is 5
The random number is 7
The random number is 8
The random number is 1
The random number is 5
The random number is 4
The random number is 4
The random number is 4
The random number is 6

Example 3.15
(The Script)
#!/usr/bin/perl
1 $x=5 ; # starting point in a range of numbers
2 $y=15; # ending point

# Formula to produce random numbers between 5 and 15 inclusive


# $random = int(rand($y - $x + 1)) + $x;
# $random = int(rand(15 - 5 + 1)) + 5

3while(1){
4 print int(rand($y - $x + 1)) + $x , "\n";
5 sleep 1;
}

Output:
15
14
5
10
11

Basic Perl © 2006 Learning Enterprises, Inc.


64 Module 3

6
12
6
7
10
6
8
6
15
11

Do Exercise 3

Perl Programming Copyright 2008, Learning Enterprises, Inc.


Operator, operator... 65

3.12 Conditional Statements and Loops


3.13 If/else
• A group of statements, called a BLOCK, is enclosed in curly braces.
• Unlike C, curly braces are required even with one statement.

Format:
if ( EXPR ) { BLOCK}
if ( EXPR ){ BLOCK} else{ BLOCK}
if ( EXPR ) { BLOCK} elsif ( EXPR ){ BLOCK }... else{ BLOCK}
unless ( EXPR ) { BLOCK }
unless ( EXPR ) { BLOCK } else { BLOCK }
unless ( EXPR ) { BLOCK} elsif ( EXPR ){ BLOCK }... else{ BLOCK}

Example 3.16
1 if ( $answer eq "yes" ){ print "Let’s move on!\n"; }

Example 3.17
(The Script)
#!/usr/bin/perl
# Script: cond_statement_ex1
2 while(<>){
3 ($name, $phone)=split(/:/);
4 unless ( $name eq ”Betty Boop” ){
5 print ”$name––$phone\n”;
6 }
7 }

Example 3.18
(The Script)
#!/usr/bin/perl
# Script: cond_statement_ex2
1 print ”What version of the operating system are you using? ”;
2 chomp($os=<STDIN>);
3 if ( $os > 2.2 ) { # Braces required always
print ”Most of the bugs have been worked out.\n”;
4 }
5 else { # Braces required always
print ”Expect some problems!\n”;
}

Basic Perl © 2006 Learning Enterprises, Inc.


66 Module 3

Example 3.19
(The Script)
#!/usr/bin/perl
#Script: cond_statement_ex3
1 $hour=‘date +%H‘; # Assign the output of the UNIX date command to $hour
2 if ( $hour >= 0 && $hour < 12 ){print ”Good–morning!\n”;}
3 elsif($hour == 12 ){print ”Lunch time.\n”;}
4 elsif($hour > 12 && $hour < 17 ){print ”Siesta time.\n”;}
5 else{print ”Goodnight. Sweet dreams.\n”;}

(The Output)
Siesta time.

3.13.1 The Switch Statement

•A switch statement is another type of control statement similar to if/elsif/


else, but evaluates an expression by matching the expression to a set of case
labels. When a match is found program control is transferred to that block
where the expression matched the label value. The following example dem-
onstrates the way a switch statement is designed in the C language, PHP, etc.

switch (expression) {
case value1 :
/* statements */
break;
case value2 :
/* statements */
break;
case value3 :
/* statements */
break;
default:
/* statements */
break;
}

• Although the switch/case mechanism is a common control structure pro-


vided by most modern programming languages, it is not an official Perl5
construct, but is now found in the standard Perl library (5.10) and at CPAN
as a module called Switch.pm.
http://search.cpan.org/~rgarcia/Switch-2.13/Switch.pm. See Example 6.25.

Perl Programming Copyright 2008, Learning Enterprises, Inc.


Operator, operator... 67

Example 3.20
1 use Switch;
print "What is your favorite color? ";
chomp($color=<STDIN>);
2 switch("$color"){
3 case "red" { print "Red hot peppers!\n"; }
case "blue" { print "I got a feeling called the blues.\n"; }
case "green" { print "How green my valley\n";}
case "yellow" { print "In my yellow submarine";}
4 else { print "$color is not in our list.\n";}
}
print "Execution continues here....\n";

(Output)
What is your favorite color? blue
I got a feeling called the blues.
Execution continues here....

Basic Perl © 2006 Learning Enterprises, Inc.


68 Module 3

3.14 Loops
• Loops are used to execute a segment of code repeatedly.
• Perls’s basic looping constructs are:

while
until
for
foreach

• Each loop is followed by a block of statements. The statement or


statements must be enclosed in curly braces.

3.15 The while loop


• The while statement executes the block as long as the expression after
the while is true.
• An expression is true if it evaluates to non–zero or null; while(1) is always
true and loops forever.
• An expression is false if it evaluates to zero or null; while(0) is false and
never loops.

Format:
while ( EXPR ) {BLOCK}

Example 3.21
(The Script)
#!/usr/bin/perl
# Script: while_loop
1 $num=0; #initialize
2 while($num <= 10 ){ # test expression;
# loop quits when expression is false or 0
3 print “$num ”;
4 $num++; # update the loop variable $num; increment $num
}
5 print “\nOut of the loop.\n”;

(The Output)
0 1 2 3 4 5 6 7 8 9 10
Out of the loop.

Perl Programming Copyright 2008, Learning Enterprises, Inc.


Operator, operator... 69

3.15.1 The do-while loop


• The do-while statement executes the block at least once before testing
the while expression.

1 $x=0;
2 do{ # block is executed before while expression is tested.
print $x;
$x++;
}while($x < 10);

3.16 The until loop


• The until statement executes the block as long as the expression after the
until is not true.
• An expression is not true if it evaluates to zero;
• An expression is true if it evaluates to non–zero;

Format:
until ( EXPR ) {Block}

Example 3.22
(The Script)
#! /usr/bin/perl
#Script: until_loop
1 $num=0; # initialize $num
2 until ($num == 10) { # test expression;
# loop quits when expression is true or non–0
3 print $num++, ” ”; # update the loop variable $num; increment $num
}
print ”\nOut of the loop.\n”;

(The Output)
0123456789
Out of the loop.

Basic Perl © 2006 Learning Enterprises, Inc.


70 Module 3

3.17 The for loop


• The for statement is like the C for loop.
• The for keyword is followed by three expressions separated by semi–
colons and enclosed within parentheses.
• Any or all of the expressions can be omitted, but the two semi–colons can-
not.
• The first expression is used to set the initial value of variables; the second
expression is used to test whether the loop should continue or stop; and the
third expression updates the loop variables.
• The infinite loop can be written as: for(;;);

Format:

for(EXPR;EXPR;EXPR){BLOCK}

Example 3.23
(The Script)
#!/usr/bin/perl
#Script: for_loop
1 for($i=0;$i<10;$i++){ # initialize, test, and increment $i
2 print “$i ”;
}
3 print ”\nOut of the loop.\n”;

(The Output)
0123456789
Out of the loop.

Perl Programming Copyright 2008, Learning Enterprises, Inc.


Operator, operator... 71

3.17.1 while Vs. for loop

Example 3.24
This example shows the differences between the for and while loops.
(The Script)
#!/usr/bin/perl
# Script: while_vs_for_loop
1 $count=1;#Initialize variables
2 $beers=10;
3 $remain=$beers;
4 $where=“on the shelf”;
5 while($count <= $beers) {
6 if($remain == 1){print “$remain bottle of beer $where $where ” ;}
7 else{ print “$remain bottles $where $where”;}
8 print “ Take one down and pass it all around.\n”;
9 print “Now ”, $beers – $count , ” bottles of beer $where!\n”;
10 if ( $count == 10 ){print “Party’s over. \n”;}
11 $count++;
12 $remain––;
}
print “\n”;
print ’_’ x 30,“\n\n”;
# Initialization, test, and increment, decrement of counters is done in one step.
13 for ($count=1, $beers=10, $remain=$beers; $count <= $beers; $count++,
$remain––){
14 if($remain == 1){print “$remain bottle of beer $where $where ” ;}
15 else{ print “$remain bottles $where $where”;}
16 print “ Take one down and pass it all around.\n”;
17 print “Now ”, $beers – $count , “ bottles of beer $where!\n”;
18 if ( $count == 10 ){print “Party’s over.\n”;}
}

Basic Perl © 2006 Learning Enterprises, Inc.


72 Module 3

3.18 The foreach loop

• The foreach loops over each element in the parenthesized list, ARRAY,
assigning each element of the array to a variable, VARIABLE. If VARI-
ABLE is absent, $_ is used.
• The VARIABLE is local to the foreach block. It will regain its former
value when the loop is exited.
• If ARRAY is an array, the array elements can be modified within the loop.

Format:
foreach VARIABLE ( ARRAY ) { BLOCK }

Example 3.25
(In Script)
#!/usr/bin/perl
#Script: foreach_loop_ex1
1 foreach $pal ( ’Tom’, ’Dick’, ’Harry’, ’Pete’ ) {
2 print ”Hi $pal\n”;
}

(The Output)
2 Hi Tom
HI Dick
Hi Harry
HI Pete

Example 3.26
(In Script)
#!/usr/bin/perl
# Script: foreach_loop_ex2
1 foreach $hour ( 0 .. 23 ){
2 print “Good–morning.\n” if $hour > 0 && $hour < 12;
3 print “Happy Lunch.\n” if $hour == 12;
4 print “Good afternoon.\n” if $hour > 12 && $hour <= 17;
5 print “Good–night.\n” if $hour > 17 && $hour < 24;
}

Perl Programming Copyright 2008, Learning Enterprises, Inc.


Operator, operator... 73

3.19 Loop Control

3.19.1 To control the flow of loops

next
next LABEL
last
last LABEL
redo
redo LABEL

• The next statement restarts the next iteration of the loop, skipping over the
rest of the statements in the loop and evaluating the loop expression, like a
C or Csh continue statement.
• The last statement leaves a block and is like the break statement in C and
Csh.
• The redo statement restarts the block without evaluating the loop expres-
sion again.
• The continue block is executed just before the conditional expression is
about to be evaluated again.

3.19.2 Labels and Loops

Format:
LABEL: while ( EXPR ){ BLOCK}
LABEL: while ( EXPR ) { BLOCK} continue{ BLOCK}
LABEL: until ( EXPR ) { BLOCK} { BLOCK}
LABEL: for ( EXPR; EXPR; EXPR ){ BLOCK}
LABEL: foreach VAR ( ARRAY ){ BLOCK}
LABEL: { BLOCK} continue { BLOCK }

3.19.3 A Labeled Block without a Loop

• A block is like a loop that executes once. A block can be labeled.


• The redo statement causes control to start at the top of the innermost or
labeled block without reevaluating the loop expression if there is one. (sim-
ilar to a goto)

Basic Perl © 2006 Learning Enterprises, Inc.


74 Module 3

Example 3.27
#!/usr/bin/perl
# Script: labeled_block
1 TRY:{
2 print ”Are you a great person? ”;
3 chomp($answer = <STDIN> );
4 redo TRY unless ”$answer” eq "yes";
}

Example 3.28
In the following example the label is optional. It is used most effectively in nested
loops.
( In Script )
#!/usr/bin/perl
#Script: labels_and_loops
1 ATTEMPT: while (1){ # ATTEMPT is a loop label

2 print “What was your grade? ”;


3 $grade = <STDIN>;

4 if ( $grade < 0 || $grade > 100 ) {


5 print “Illegal choice\n”;
6 next; } # start control at the beginning of the innermost loop
8 if ( $grade > 89 && $grade < 101 ){ print ”A\n”;}
elsif ( $grade > 79 && $grade < 90 ) { print ”B\n”;}
elsif ( $grade > 69 && $grade < 80 ) { print ”C\n”;}
elsif ( $grade > 59 && $grade < 70 ) { print ”D\n”;}
elsif ( $grade >= 0 && $grade < 60 ) { print ”You Failed.”;}

9 print "Would you like to enter another grade? (y/n)? ”;


10chomp($choice = <STDIN>);
11 if( $choice ne "y") { last ATTEMPT;}
}
12 print "That’s all folks!!\n";

Perl Programming Copyright 2008, Learning Enterprises, Inc.


Operator, operator... 75

Exercise 3A
Operator, operator

1. Print the average of three floating point numbers with a precision of two
decimal places.

2. a. What are two other ways that you could write:

$x = $x + 1;

b. Write the following expression using a short–cut:

$y = $y + 5;

3. Calculate the volume of a room that is 12.5 ft long and 9.8 ft wide and
10.5 ft high.

4. Square the number 15 and print the result.

5. Write a program called ’convert’ that converts a Fahrenheit temperature


to Celsius using the following formula.

C = ( F – 32 ) / 1.8

4. The following formula is used to calculate the fixed montly payment


required to fully amoritize a loan over a term of months at a monthly inter-
est rate. Write a Perl expression to represent the following formula where:
P = principal amount borrowed, r = periodic interest rate (annual interest
rate divided by 12), n = total number of payments (for a 30-year loan with
monthly payments, n = 30 years × 12 months = 360), and A = periodic pay-
ment.

Basic Perl © 2006 Learning Enterprises, Inc.


76 Module 3

5. Create an array of common sayings; for example:

An apple a day keeps the doctor away.


A stitch in time saves nine.
Procrastination is the thief of time.
Handsome is as handsome does.
Too many cooks spoil the broth.
A watched pot never boils.
Many hands make light work.

Randomly print a saying each time the user runs your script. Hint: The
index value of the array will be randomly generated to produce the saying.

Exercise 3B
What Are Your Conditions?
A. Temperature Conversion Script

1. Physicists tell us that the lowest possible temperature is absolute zero.


Absolute zero is –459.69 degrees Fahrenheit.

Write a temperature conversion program to:

a. Accept inputs from the user: a beginning temperature, an ending temper-


ature, and an increment value. (All Fahrenheit)

b. Check for bad input: a temperature less than absolute zero and an ending
temperature that is less than the beginning temperature. The program will
send an error message to STDERR if either condition is detected.

c. Print out a header showing: ”Fahrenheit Celsius”.


Print out all values from the beginning to the ending temperature using a
loop.

The conversion formula is:


C = ( F – 32 ) / 1.8

Perl Programming Copyright 2008, Learning Enterprises, Inc.


Operator, operator... 77

B. Looping Through a Set of Grades

2. a.Ask the user for a list of grades separated by whitespace.


b. The grades will be stored in a scalar string called $input.
c. Split the string and create an array.
d. Use the foreach loop to get the total sum of all the grades.
e. Print the average.

C. Shuffle the Deck


3. a. Write a script that will print 10 random number cards from a deck.
b. The script will build deck of 52 cards by using nested foreach loops.
c. The outer loop will iterate through a list consisting of card for each suit:
clubs, diamonds, hearts, spades. The inner loop will iterate through a list for
each type of card within the suit: ace, 1 through 10 jack, queen, and king. A
card of each suit will be assigned to an array
d. The rand() function will be used to get a random card from the pack.
There should be no duplicates in the 10 cards selected from the deck.

Basic Perl © 2006 Learning Enterprises, Inc.


78 Module 3

Perl Programming Copyright 2008, Learning Enterprises, Inc.


79

Module 4
Regular Expressions
4.1 Pattern Matching
• A regular expression is a pattern of characters that is used when searching
for a specified pattern of characters in a line of text. The regular expression
can be a word or part of a word and can contain metacharacters.
• Regular expressions in Perl are simply patterns of characters. The pattern
is enclosed in forward slashes.
• The metacharacters are special characters embedded in regular expres-
sions that allow you to control the way a search performed.

4.2 Simple Statements and Modifiers


• Every statement is an expression terminated with a semi–colon.
• A simple statement may contain an expression ending with a single state-
ment modifier.
• The modifier is followed by a semi–colon.
• Compound statements are built from expressions and blocks. Compound
statements are discussed in Module 5.

Modifiers are:
if EXPR
unless EXPR
while EXPR
until EXPR
foreach EXPR

Basic Perl © 2006 Learning Enterprises, Inc.


80 Module 4

4.2.1 Conditional Modifiers


• The if and unless modifiers control a simple statement based on some con-
dition.

Example 4.1
In this example, the special filehandle, DATA, is used to read input lines. The
actual data is stored under the special literal __DATA__. This is handy if you
don’t want to open an external file to do simple testing.

(In Script)
while (<DATA>){
print;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

Basic Perl © 2006 Learning Enterprises, Inc.


81

Example 4.2
Print the line if it contains Norma

while (<DATA>){
print if /Norma/;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
4 Norma Cord

Example 4.3
The Modifier must be placed at the end of a statement!

while (<DATA>){
if /Norma/ print; # could be: if (/Norma/){ print; }
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
syntax error in file /tmp/perl–ea01985 at line 1, next 2 tokens ”if /Norma/”
Execution of /tmp/perl–ea01985 aborted due to compilation errors

Example 4.4
Print the line unless it contains Norma

while (<DATA>){
print unless /Norma/;
}
__DATA__
1 Steve Blenheim

Basic Perl © 2006 Learning Enterprises, Inc.


82 Module 4

2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
5 Jon DeLoach
6 Karen Evich

4.3 Matching and Substitution Operations


• Regular expressions in Perl are simply patterns. The regular expression meta-
characters are listed in section 1.3.
• The pattern matching operators are the m// operator and the s/// operator.
• The m operator is used for matching patterns.
• The s operator is used for substitutions.

4.4 The match operator

• The m operator is optional if the delimiter is the forward slash, but


required if you change the delimiter.
• If the pattern is delimited by question marks, only the first occurrence of
the matched pattern is matched. (The reset function allows you to resume
the search.)

1 m/Good morning/
2 /Good morning/
3 m#Good morning#
4 /good MORning/i

Basic Perl © 2006 Learning Enterprises, Inc.


83

4.5 The substitution operator


• The s operator changes the first regular expression pattern to the second.
The delimiter can also be changed.
• The g stands for global; i.e. change multiple entries on the line.
Without it the substitution occurs only for first occurrence of the patter on
the line. The i turns off case sensitivity. The e causes the expression in the
replacement side to be an executed as a statement

1 s/old/new/
2 s/old/new/i
3 s/old/new/g
4 s+old+new+g
5 s/old/expression to be executed/e

Example 4.5
Substitute Igor with Boris. Print all lines.

while(<DATA>){
s/Igor/Boris/;
print; # Prints all lines
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
1 Steve Blenheim
2 Betty Boop
3 Boris Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

Basic Perl © 2006 Learning Enterprises, Inc.


84 Module 4

Example 4.6
Print the line only if Igor is replaced with Boris.

while(<DATA>){
print if s/Igor/Boris/;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
3 Boris Chevsky

Example 4.7
The i modifier turns off case sensitivity. Replace Igor with Boris ignoring the
case in the search pattern; i.e. Igor, IGOR, IGor, etc.

while(<DATA>){
print if s/igoR/Boris/i;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
3 Boris Chevsky

Basic Perl © 2006 Learning Enterprises, Inc.


85

Example 4.8
Replace the first ’e’ on each line with an ’X’.

while(<DATA>){
print if s/e/X/;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
1 StXve Blenheim
2 BXtty Boop
3 Igor ChXvsky
5 Jon DXLoach
6 KarXn Evich

Example 4.9
Replace every occurrence of ’e’ on the line with an ’X’.

while(<DATA>){
print if s/e/X/g;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
1 StXvX BlXnhXim
2 BXtty Boop
3 Igor ChXvsky
5 Jon DXLoach
6 KarXn Evich

Basic Perl © 2006 Learning Enterprises, Inc.


86 Module 4

Example 4.10
Globally substitute every ’e’ or ’E’ for ’X’ (turn off the case sensitivity)

while(<DATA>){
print if s/e/X/gi;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
1 StXvX BlXnhXim
2 BXtty Boop
3 Igor ChXvsky
5 Jon DXLoach
6 KarXn Xvich

Example 4.11
Substitute the search string with the replacement string after the expression
( 6 * 5 + 4 ) has been evaluated.

while(<DATA>){
print if s/6/6 * 5 + 4/e; # Evaluate the expression
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
34 Karen Evich

Basic Perl © 2006 Learning Enterprises, Inc.


87

Example 4.12
Globally substitute the search string with the replacement string after the ex-
pression ( "*" x 3 ) has been evaluated ( turn off case sensitivity).

while(<DATA>){
print if s/e/"*" x 3/eig; # Globally, evaluate, turn off case
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
1 St***v*** Bl***nh***im
2 B***tty Boop
3 Igor Ch***vsky
5 Jon D***Loach
6 Kar***n ***vich

4.6 Pattern Matching Operators


• The pattern matching operators are used when the default scalar, $_ , is not
being matched against.

Expression What It Means


$name =~ /John/ True if $name contains pattern.
Returns 1 for true, null for false.
$name !~ /John/ True if $name does not contain pattern.
$name =~ s/John/Sam/ Replace first occurrence of John with Sam.
$name =~ s/John/Sam/g Replace all occurrences of John with Sam.
$name =~ tr/a–z/A–Z/ Translate all lower case letters to upper case.
$name =~ /$pal/ A variable can be used in the search string.

Example 4.13
(In Script)
1 while(<>){
2 print if /^Igor/;
}
#The $_ variable holds the current line and is matched if it begins with the pat-
tern Igor

Basic Perl © 2006 Learning Enterprises, Inc.


88 Module 4

Example 4.14
(In Script)
1 while(<>){
2 ($name, $phone, $address) = split(":", $_);
3 print if $phone =~ /^397/;
}
# $phone is matched if it begins with the pattern 397.

Example 4.15
(The Script)
1 #!/usr/bin/perl
2 # pattern matching script perl.pat
3 $name=“Tommy Tuttle”;
4 print $name=~/Tom/, ”\n”; #prints 1 if true
5 print $name=~/Joe/, ”\n”; #print null if false
6 $name=~s/T/M/; print $name,”\n”; #substitute first ‘T’ with an ‘M’
7 $name=”Tommy Tuttle”;
8 $name=~s/T/M/g; print $name,”\n”; #substitute all ‘T’s’ with ‘M’s’
9 $message=“merry christmas”;
10$message=~tr/a–z/A–Z/; # translate all lower case letters to uppercase
11print “$message\n”;

(The Output)
4 1
5
6 Mommy Tuttle
8 Mommy Muttle
11 MERRY CHRISTMAS

Basic Perl © 2006 Learning Enterprises, Inc.


89

4.7 The RE Metacharacters

Metacharacter Function
. Matches any character except newline
[a–z0–9] Matches any single character in set
[^a–z0–9] Matches any single character not in set
\d Matches one digit
\D Matches a non–digit, same [^0–9]
\w Matches an alpha–numeric ( word ) character
\W Matches a non–alpha–numeric ( non–word ) character
\s Matches white space character
\S Matches non–white space character
\n Matches a newline
\r Matches a return
\t Matches a tab
\f Matches a formfeed
\b Matches a backspace(when inside [ ])
\0 Matches a null character
\12 Matches that octal value
\x811 Matches that hex value
\cX Matches that control character
\[ Matches that metacharacter
(string) Used for backreferencing ( see example )
\1 or $1 Matches first set of parens
\2 0r $2 Matches second set of parens
\3 or $3 Matches third set of parens
x? Matches 0 or 1 x
x* Matches 0 or more x’s
x+ Matches 1 or more x’s
x{m,n} Matches at least m, x’s and no more than n x’s.
abc Matches all of a, b, and c respectively

Basic Perl © 2006 Learning Enterprises, Inc.


90 Module 4

was|were|will Matches one of was, were, or will


\b Matches a word boundary ( When not inside [ ] )
\B Matches a non–word boundary
^ Matches to beginning of line
$ Matches to end of line

Examples:

1 /love/ matches love no matter what letters


precede or follow the expression.

2 /^love/ matches only if love is at


the beginning of the line.

3 /love$/ matches only if love is at the end of


the line.

4 /l.ve/ matches love, live, will verify, etc.

5 /[Ll]ove/ matches love, Love or glove, etc.

6 /lo*ve/ matches love, valve,


glooooooove, etc.

7 /\blove\b/ matches only if love is a word.

8 /lov(ing|er|eable)/ matches loving or lover or loveable

9 /love\./ matches love followed by a literal period

Basic Perl © 2006 Learning Enterprises, Inc.


91

4.7.1 Anchors

Example 4.16
Print lines starting with the number 5.

while(<DATA>){
print if /^5/ ;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
5 Jon DeLoach

Example 4.17
Print lines ending with "ch".

while(<DATA>){
print if /ch$/ ;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
5 Jon DeLoach
6 Karen Evich

Example 4.18
Print “Found Norma” if the “word” Norma is found.

while(<DATA>){
print "Found Norma!\n" if /\bNorma\b/;

Basic Perl © 2006 Learning Enterprises, Inc.


92 Module 4

}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
Found Norma!

4.8 The Dot


The dot represents any single character other than the newline. To match
on a literal period the dot is escaped with a backslash.

Example 4.19
Find all lines containing a space, followed by three characters, and another
space.

while(<DATA>){
print if / ... /;
}

__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
5 Jon DeLoach

Example 4.20
Substitute the first character with an ’X’, no matter what character it is.

while(<DATA>){
print if s/./X/;
}
__DATA__

Basic Perl © 2006 Learning Enterprises, Inc.


93

1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
X Steve Blenheim
X Betty Boop
X Igor Chevsky
X Norma Cord
X Jon DeLoach
X Karen Evich

Example 4.21
Substitute “N", followed by any two characters, followed by "ma”, with
“Jane”. Print all lines.

while(<DATA>){
s/N..ma/Jane/;
print;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Jane Cord
5 Jon DeLoach
6 Karen Evich

Basic Perl © 2006 Learning Enterprises, Inc.


94 Module 4

4.9 Character Sets


Example 4.22
Print lines containing an A, B, or C.

while(<DATA>){
print if /[ABC]/;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord

Example 4.23
Print lines containing a character in the set, ranging from E to M.

while(<DATA>){
print if /[E-M]/;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
3 Igor Chevsky
5 Jon DeLoach
6 Karen Evich

Basic Perl © 2006 Learning Enterprises, Inc.


95

Example 4.24
Print lines beginning with one of the numbers not in the set 2, 3, or 4.

while(<DATA>){
print if /^[^2-4]/;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
1 Steve Blenheim
5 Jon DeLoach
6 Karen Evich

4.10 Metasymbols to Represent Single Characters


TABLE 4.1 Metasymbols and what they mean
\d A single digit, same as [0-9]
\w An alphanumeric word character, same as [A-Za-z0-9_]
\s A single space
\D A single non-digit, same as [^0-9]
\W A single non alphanumeric word character, same as [^A-Za-z0-9_]
\S A single non-space character

Example 4.25
Print lines beginning with a single digit, followed by a space (or tab), followed
by three alphanumeric word characters and a space..

while(<DATA>){
print if /^\d\s\w\w\w\s/;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

Basic Perl © 2006 Learning Enterprises, Inc.


96 Module 4

(Output)
5 Jon DeLoach

4.11 Quantifiers ( * + ? )

TABLE 4.2 The Greedy Metacharacters


Metacharacter What It Matches
x? Matches 0 or 1 x
(xyz)? Matches xero or one pattern of xyz.
x* Matches 0 or more x’s
(xyz)* Matches xero or more patterns of xyz.
x+ Matches 1 or more x’s
(xyz)+ Matches one or more patterns of xyz.
x{m,n} Matches at least m, x’s and no more than n x’s.

Example 4.26
Print lines matching a B followed by zero or more lowercase letters.

while(<DATA>){
print if /B[a-z]*/; # Zero or more letters between ’a’ and ’z’
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich
7 B B King # Added this line for example

(Output)
1 Steve Blenheim
2 Betty Boop
7 B B King

Example 4.27
Print lines matching a B followed by one or more lowercase letters.

while(<DATA>){
print if /B[a-z]+/; # One or more letters between ’a’ and ’z’
}
__DATA__

Basic Perl © 2006 Learning Enterprises, Inc.


97

1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich
7B B King # Added this line for example

(Output)
1 Steve Blenheim
2 Betty Boop

Example 4.28
Print lines matching an ’e’ followed zero or one spaces and an upper case
letter.

while(<DATA>){
print if /e\s?[A-Z]/;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
1 Steve Blenheim
5 Jon DeLoach

4.12 Alternation
Example 4.29
Print lines that match Steve, Betty, or Jon

while(<DATA>){
print if /Steve|Betty|Jon/; # Alternation: this, that, and the other thing
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky

Basic Perl © 2006 Learning Enterprises, Inc.


98 Module 4

4 Norma Cord
5 Jon DeLoach
6 Karen Evich

Output:
1 Steve Blenheim
2 Betty Boop
5Jon DeLoach

4.13 Grouping
Example 4.30
Print lines that match one or more occurrences of ’ma’.

while(<DATA>){
print if /(ma)+/i;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich
7Mama Bear # Line added for this example

(Output)
4 Norma Cord
7 Mama Bear

Example 4.31
Print lines that match Steve Blenheim or Alexander Blenheim

while(<DATA>){
print if /(Steve|Alexander) Blenheim/;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

Basic Perl © 2006 Learning Enterprises, Inc.


99

7Alexander Blenheim # Line added for this example

Output:
1 Steve Blenheim
7 Alexander Blenheim

4.14 Capturing Patterns ($1 $2 $3 ... )


Example 4.32
Find a space, followed by one or more word characters, another space, and
one or more word characters. Save the first set of word characters in paren-
theses into a variable called $1 and the second set into a variable called $2.
Print the values of the captured pattern.

while(<DATA>){
/\s(\w+)\s(\w+)/;
print "$1 $2\n";
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
Steve Blenheim
Betty Boop
Igor Chevsky
Norma Cord
Jon DeLoach
Karen Evich

Basic Perl © 2006 Learning Enterprises, Inc.


100 Module 4

Example 4.33
Find “Jon” or “jon”, capture the pattern found, store it in $1, and use it in the
replacement string to produce “Jonathan ” or “jonathan.

while(<DATA>){
s/([Jj]on)/$1athan/;
print;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jonathan DeLoach
6 Karen Evich

Example 4.34
Reverse “Steve” and “Blenheim”

while(<DATA>){
print if s/(Steve) (Blenheim)/$2, $1/;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach

(Output)
1 Blenheim, Steve

Basic Perl © 2006 Learning Enterprises, Inc.


101

Example 4.35
Reverse first and last names

while(<DATA>){
s/([A–Z][a–z]+)\s([A–Z][a–z]+)/$2, $1/;
print;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
1 Blenheim, Steve
2 Boop, Betty
3 Chevsky, Igor
4 Cord, Norma
5 De, JonLoach # Whoops!
6 Evich, Karen

Try this: s/^(\d+)\s(\w+)\s(\w+)/$1 $3,$2/;

4.15 Repeating Patterns


Example 4.36
Print lines beginning with one digit, followed by a space, exactly 5 word char-
acters, and a space.

while(<DATA>){
print if /^\d\s\w{5}\s/;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

Basic Perl © 2006 Learning Enterprises, Inc.


102 Module 4

(Output)
1 Steve Blenheim
2 Betty Boop
4 Norma Cord
6 Karen Evich

Example 4.37
Print lines containing at least 15 characters

while(<DATA>){
print if /.{15,}/;
}
__DATA__
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich

(Output)
1 Steve Blenheim

Basic Perl © 2006 Learning Enterprises, Inc.


103

Exercise 4A
Regular Expressions––They’re Back...
(Sample file)
Tommy Savage:408–724–0140:1222 Oxbow Court, Sunnyvale,CA 94087:5/19/66:34200
Lesle Kerstin:408–456–1234:4 Harvard Square, Boston, MA 02133:4/22/62:52600
JonDeLoach:408–253–3122:123 Park St., San Jose, CA 94086:7/25/53:85100
Ephram Hardy:293–259–5395:235 Carlton Lane, Joliet, IL 73858:8/12/20:56700
Betty Boop:245–836–8357:635 Cutesy Lane, Hollywood, CA 91464:6/23/23:14500
Wiliam Kopf:846–836–2837:6937 Ware Road, Milton, PA 93756:9/21/46:43500
Norma Corder:397–857–2735:74 Pine Street, Dearborn, MI 23874:3/28/45:245700
James Ikeda:834–938–8376:23445 Aster Ave., Allentown, NJ 83745:12/1/38:45000
Lori Gortz:327–832–5728:3465 Mirlo Street, Peabody, MA 34756:10/2/65:35200
Barbara Kerz:385–573–8326:832 Ponce Drive, Gary, IN 83756:12/15/46:268500

1. Print all lines containing the pattern “Street”.

2. Print lines where the first names start with “B”.

3. Print last names that match “Ker”.

4. Print phones in the 408 area code.

5. Print Lori Gortz’s name and address.

6. Print Ephram’s name in capital letters.

7. Print lines that do not contain a “4”.

8. Change William’s name to Siegfried.

9. Print Tommy Savage’s birthday.

10. Print lines that end in exactly 5 digits..

11. Print the file with the first and last names reversed.

Basic Perl © 2006 Learning Enterprises, Inc.


104 Module 4

Exercise 4B
IS IT SED, AWK, OR GREP?
GIVE PERL A WHIRL!

1. Print the city and state where Norma lives.

2. Give everyone a $250.00 raise.

3. Calculate Lori’s age. ( just by year, not month and day)

4. Print lines 2 through 6. ( The $. variable holds the current line number. )

5. Print names and phone numbers of those in the 408 area code.

6. Print names and salaries in lines 3, 4, and 5.

7. Print a row of stars after line 3.

8. Change “CA” to ”California”.

9. Print the file with a row of stars after the last line.

10. Print the names of the people born in March.

11. Print all lines that don’t contain Karen.

12. Print all cities in California, and the first names of those people who live there.

13. Without using the split function, print all the lines up to the first colon (Just the names)

14.Without using the split function, print the street address; e.g. 123 Park St.

15. Create and display a new format for all the phone numbers to look like this:

(408) 465-1234

Basic Perl © 2006 Learning Enterprises, Inc.


Getting a Handle on Files 105

Module 5
Getting a Handle on Files
5.1 User–Defined Filehandles
• A filehandle is a name for a file, device, pipe or socket.
• The open function allows you to create your own filehandle
• The $_ scalar variable is used as the default pattern space for
searches.
It is also used to hold the current line.
• A filehandle remains opened until explicitly closed or the program ends.

5.2 A Little About Dying


• When opening files or pipes a system call makes a request to the kernel.
If the system call fails, it will print an error message, such as "No such file
or directory". The die function is commonly used to catch the error message
and force your script to exit.

• The die function prints a concatenated LIST to STDERR and exits with
the current value of $!, the system error message that you would normally
get if a system call failed. If the LIST does not end in a newline, the die func-
tion prints the LIST and the line where the program died.

Example 5.1
(In a Script)
# The chdir function will try to change directories to /usr/bin/joker
1 chdir "/usr/bin/joker" || die "Can’t cd: $!\n";

# If the call to the system to change directories fails, the die function will
# cause the program to exit with the system message shown in the output.

(The Output)
1 Can’t cd: No such file or directory

• The module Carp.pm (Perl5) was added to refine the way a program dies.
perldoc -f die

Basic Perl © 2006 Learning Enterprises, Inc.


106 Module5

5.3 Open a File for Reading

• Perl reads from the file when the filehandle is enclosed in angle brack-
ets, called the diamond operators.

Format:
open ( Filehandle, "Unix filename" );
open ( Filehandle, "<Unix filename" );

Example 5.2
(Script)
#!/usr/bin/perl
# open_for_reading_format
1 open (MYHANDLE, “myfile” );
2 while($line=<MYHANDLE>){ # Assign each line of input to $line
3 print $line;
}
4 close(MYHANDLE);

----------------------------------------------------------------
1 open (MYHANDLE, “myfile” );
2 while(<MYHANDLE>){ # Each line is assigned to $_, the default
3 print;
}
4 close(MYHANDLE);

5.4 Close a File


After you have finished using a filehandle, it should be closed with the
close function.

Format:
close ( Filehandle );

Basic Perl © 2006 Learning Enterprises, Inc.


Getting a Handle on Files 107

Example 5.3
(The file to be opened)
1 Steve Blenheim
2 Betty Boop
3 Igor Chevsky
4 Norma Cord
5 Jon DeLoach
6 Karen Evich
---------------------------------------------------------
( In Script )
#!/usr/bin/perl
# Script: open_for_reading_example

1 open(FILE, “emp.names”) || die “Can’t open emp.names: $!\n”;


2 print “Hello to you and yours!\n”;
3 while(<FILE>) {
# FILE is attached to the UNIX file, emp.names.
# Each line from FILE is read in turn and stored in the $_ variable.
4 print “HI Betty\n” if /Betty/;
5 print ”HI Igor\n” if $_ =~ /Igor/;
}
6 close(FILE); # Close the filehandle

( The Output )

2 Hello to you and yours!


3 HI Betty
4 HI Igor

Basic Perl © 2006 Learning Enterprises, Inc.


108 Module5

5.5 Open a File for Writing


• If a file is opened for writing and it does not exist, it is created; if it exists,
it is truncated.
• It remains opened until closed or the script terminates.
• If the select function is used with a filehandle, that filehandle will become
the default filehandle for output. The select function returns the previous
selected filehandle.

Format:

open ( MYHANDLE, “> myfile”);

Example 5.4
( The Script )
#!/usr/bin/perl
# Script: open_for_writing
5 $file=“newfile”;
6 open(HANDOUT, “> $file”) || die “Can’t open $file: $!\n”;
7 print HANDOUT “hello world.\n”; # Output is sent to HANDOUT
8 print HANDOUT “hello world again.\n”;
9 close(HANDOUT);

( The Output )
$ cat newfile # After running the script, display the output file, newfile
7 hello world.
8 hello world again.

5.6 Open a File for Appending


• A file opened for appending is created if it does not exist.
• The output is appended to the end of the file.
• The filehandle remains opened until closed or the script terminates.

Format:
open ( MYHANDLE, “>> myfile”);

Example 5.5
#!/usr/bin/perl
# Script: open_for_appending
1 open(HANDOUT, “>> newfile”) or die print “Can’t open newfile: $!\n”;
2 print HANDOUT “Just appended to \“hello world\” in newfile.\n”;

Basic Perl © 2006 Learning Enterprises, Inc.


Getting a Handle on Files 109

5.7 Finding a Position in a File

5.3.1 The eof Function

• The eof function can be used to test if end of file has been reached.
• It returns 1 if either the next read on a FILEHANDLE is EOF or if the file
is not opened.
• Without an argument the eof file returns the eof status of the last file read.
• The eof function can be used in a while loop to test each file in the argu-
ment list, if it is used without parenthesis or the ARGV handle is used in
parenthesis.

Format:
eof(FILEHANDLE)
eof()
eof

Find pattern and print until the end of file is reached. (See range operator.)

Example 5.6

(In Script)
#!/usr/bin/perl
# Script: eof_function1
1 while(<>){
2 print if /pattern/ .. eof;
3 }

Print each line of the file and when end of file is reached, print a row of 30 dashes.

#!/usr/bin/perl
# Script: eof_function2
4 while(<>){
5 print;
6 if (eof) { print “–” x 30, ”\n”;}
}

Basic Perl © 2006 Learning Enterprises, Inc.


110 Module5

5.3.2 The seek Function

• The seek function is the same as the fseek standard i/o function in C.
Rather than closing the file, and then reopening it, the seek function allows
you to move to some position within the file.
• Seek allows you to randomly access a file.
• The tell function returns the current byte position in the file and is used
with the seek function to move to that position in the file.

Format:

seek(FILEHANDLE, BYTEOFFSET, FILEPOSITION)

• Seek sets a position in a file, where the first byte is 0. Positions are:

0 = Beginning of the file


1 = Current position in the file
2 = End of the file

• The offset is the number of bytes from the file position. A positive offset
moves the position forward in the file; a negative offset moves the position
backward in the file for position 1 or 2.
Example 5.7
(The Script)
1 #!/usr/bin/perl
# Script: seek_function
2 open(PASSWD,”/etc/passwd”) || die ”Can’t open: $!\n”;
3 while($line=<PASSWD>){ # loop through the whole file
4 if ($line =~ /daemon/) { print ”––$line––\n”;}
}
6 seek(PASSWD,0,0); # Seek to the beginning of the file
7 while(<PASSWD>) { # Read from the beginning of the file
8 print if /root/;
}

Basic Perl © 2006 Learning Enterprises, Inc.


Getting a Handle on Files 111

5.3.3 The tell function


• The tell function returns the current byte position for a file. Used with
seek.

Format:
tell(FILEHANDLE)
tell

Example 5.8
(The Script)
#! /usr/bin/perl
# Script: tell_function

1 open(PASSWD,”/etc/passwd”) || die ”Can’t open: $!\n”;


2 while ($line=<PASSWD>) { # loop through the whole file
3 if ($line =~ /adm/) {
4 $currentpos=tell; # $currentpos contains the byte position
5 print ”––$line––”;
}
}
6 print ”The current byte postion is ”, $currentpos,”\n”;
7 seek(PASSWD,$currentpos,0); # From start of the file go to $currentpos
8 while(<PASSWD>) {
9 print;
}

Basic Perl © 2006 Learning Enterprises, Inc.


112 Module5

5.4 File Testing


• Perl provides a number of file test operators to check for the various
attributes of a file, such as existence, access permissions, directories, files,
etc.
• Most of the operators return 1 for true and ’ ’ for false.
• A single underscore can be used to represent the name of the file if the
same file is tested more than once. The stat structure of the previous file
test is used.

Operator What it Tests


–r $file True if $file is a readable file.
–w $file True if $file is a writeable file.
–x $file True if $file is an executable file.
–o $file True if $file is owned by effective uid.
–e $file True if $file exists.
–z $file True if $file is zero in size
–s $file True if $file has non–zero size. Returns the size of the file in bytes.
–f $file True if $file is a plain file.
–d $file True if $file is a directory file.
–l $file True if $file is a symbolic link.
–p $file True if $file is a named pipe or FIFO.
–S $file True if $file is a socket.
–b $file True if $file is a block special file.
–c $file True if $file is a character special file.
–u $file True if $file has a setuid bit set.
–g $file True if $file has a setgid bit set.
–k $file True if $file hs a sticky bit set.
–t $file True if $file is opened to a tty.
–T $file True if $file is a text file.
–B $file True if $file is a binary file.
–M $file Age of the file in days since modified.
–A $file Age of the file in days since last accessed.
–C $file Age of the file in days since the inode changed.

Example 5.9
(Check the permissions on perl.test)
1 $ ls –l perl.test
–rwxr–xr–x 1 ellie 417 Apr 23 13:40 perl.test

2 $ ls –l afile
–rws––x––x 1 ellie 0 Apr 23 14:07 afile

Basic Perl © 2006 Learning Enterprises, Inc.


Getting a Handle on Files 113

(In Script)
#!/usr/bin/perl
# Script: file_testing_ex1

$file=perl.test;

1 print “File is readable\n” if –r $file;


2 print “File is writeable\n” if –w $file;
3 print “File is executable\n” if –x $file;
4 print “File is a regular file\n” if –f $file;
5 print “File is a directory\n” if –d $file;
6 print “File is text file\n” if –T $file;
7 printf “File was last modified %f days ago.\n”, –M $file;
8 print ”File has read, write, and execute set.\n”if –r $file && –w _ && –x _;
9 stat(“afile”); # stat another file
10print ”File is a set user id program.\n” if –u _;
#underscore evaluates to last file stat’ed
11 print ”File is zero size.\n” if –z _;
12stat(”xxyyzz”) || die ”xxyyzz: $!\n;

(The Output)
1 File is readable
2 File is writeable
3 File is executable
4 File is a regular file
5 *** No print out here because the file is not a directory ***
6 File is text file
7 File was last modified 0.000035 days ago.
8 File has read, write, and execute set.
10File is a set user id program.
11 File is zero size.
12xxyyzz: No such file or directory

Basic Perl © 2006 Learning Enterprises, Inc.


114 Module5

Example 5.10
(The Script)
#! /usr/bin/perl
#Script: file_testing_ex2
#
1 open(FIND,”find . –name ’perl*’ –print |”) || die ”UNIX find command failed: $!\n”;
2 while($filename=<FIND>) {
3 chomp $filename ; # get rid of that trailing newline. Important!
4 if ( –r $filename && –w _ && –x _) {
5 print ”$filename is readable, writeable, and executable.\n”; }
6 if ( –T $filename) {
print ”$filename is a text file.\n”;
}
}
––––––––––––––––––––––––––––––––––––––––––––––
If the –T or –B switches are used first block of the file is examined for weird char-
acters. If over 30% of the characters are weird, such as control characters, then
the file is a –B (block special file); otherwise the file is a –T ( file text file).

5.5 Passing Arguments to a Script


5.6 The ARGV Array
• Perl stores arguments in a special array called ARGV. The subscript
starts at zero.

• Unlike C and awk, ARGV[0] does not represent the name of the pro-
gram; it represents the name of the first word after the script name.

• Like the shell languages, the $0 special variable is used to hold the name
of the Perl script.

• The $#ARGV variable contains the number of the last subscript in the
array, not the number of elements in the array.

• The number of arguments is $#ARGV + 1. $#ARGV initially has a value


of -1.

• When ARGV, the filehandle, is enclosed in angle brackets, <ARGV>,


the command line argument is treated as a filename. The filename is

Basic Perl © 2006 Learning Enterprises, Inc.


Getting a Handle on Files 115

assigned to ARGV and the @ARGV array is shifted immediately to the left
by one, thereby shortening the @ARGV array. The value that is shifted off
the @ARGV array is assigned to $ARGV.

$ARGV contains the name of the currently selected filehandle.

Example 5.11
(The Script)
$!/usr/bin/perl
1 die "$0 requires an argument.

# Must have at least one argument


2 print "@ARGV

3 print "$ARGV[0]

4 print "$ARGV[1]

5 print "There are ", $#ARGV + 1," arguments.

# $#ARGV is the last subscript


6 print "$ARGV[$#ARGV] is the last one.

(Output)
$ perl.arg
2 perl.arg requires an argument.

$ perl.arg f1 f2 f3 f4 f5
2 f1 f2 f3 f4 f5
3 f1
4 f2
5 There are 5 arguments.
6 f5 is the last one.

Basic Perl © 2006 Learning Enterprises, Inc.


116 Module5

5.7 9.2.2 ARGV and the Null Filehandle


• When used in loop expressions and enclosed in the input angle brackets
(<>), each element of the ARGV array is treated as a special filehandle.

• Perl shifts through the array, storing each element of the array in a variable
$ARGV. A set of empty angle brackets is called the null filehandle and Perl
implicitly uses each element of the ARGV array as a filehandle.

• When using the input operators <>, either with or without the keyword
ARGV, Perl shifts
Example 5.12
(The Text Files)
$ cat f1
Hello there. Nice day.

$ cat f2
Are you sure about that?

$ cat f3
This is it.
This is the end.

(The Script)
1 while( <ARGV> ) {print ;}
2 print "The value of \$ARGV[0] is $ARGV[0].

(Output)
$ argv.test f1 f2 f3
Hello there. Nice day.
Are you sure about that?
This is it.
This is the end.
The value of $ARGV[0] is .

Example 5.13
(The Text File: emp.names)
Steve Blenheim
Betty Boop
Igor Chevsky
Norma Cord
Jon DeLoach

Basic Perl © 2006 Learning Enterprises, Inc.


Getting a Handle on Files 117

Karen Evich
(The Script)
# Scriptname: grab.pl
# Program will behave like grep -- will search for a pattern
# in any number of files.

Example 5.14
1 if ( ($#ARGV < 1 ) {die "Usage: $0 pattern filename(s)
2 $pattern = shift;
3 while($line=<ARGV>){
print "$ARGV: $.: $line" if $line =~ /$pattern/i;
close(ARGV) if eof;
}
(Output)
$ grab.pl
1 Usage: grab.pl pattern filenames(s)

$ grab.pl 'norma' db
2 db:5: Norma Cord

$ grab.pl 'Sir Lancelot' db


3 db:4: Sir Lancelot

$ grab.pl '^.... ' db


4 db:3: Lori Gortz

$ grab.pl Steve d*
5 datebook.master:12: Johann Erickson:Stevensville, Montana
datafile:8: Steven Daniels:496-456-5676:83755:11/12/56:20300
db:1: Steve Blenheim

Example 5.15

(The Script)
1 unless ( $#ARGV == 0 ){ die "Usage: $0 <argument>: $!"; }
2 open(PASSWD, "etc/passwd") || die "Can't open: $!";
3 $username=shift(@ARGV);
4 while( $pwline = <PASSWD>){
5 unless ( $pwline =~ /$username:/){ die "$username is not
a user here.

}
6 close PASSWD;
7 open(LOGGEDON, "who |" ) || die "Can't open: $!" ;
8 while($logged = <LOGGEDON> ){

Basic Perl © 2006 Learning Enterprises, Inc.


118 Module5

if ( $logged =~ /$username/){ $logged_on = 1; last;}


}
9 close LOGGEDON;
die "$username is not logged on.

print "$username is logged on and running these processes.

10 open(PROC, "ps -aux|" ) || die "Can't open: $! ";


while($line=<PROC>){
print "$line" if $line =~ /$username:/;
}
11 close PROC;
print '*' x 80; "

Basic Perl © 2006 Learning Enterprises, Inc.


Getting a Handle on Files 119

Exercise 5
Getting A Handle on Things
5A
1. Create a filehandle for reading from the ”datebook” file; print to another
filehandle the names of all those who have a salary greater than $50,000.

2. Ask the user to input data for a new entry in the ”datebook” file. (The
name, phone, address, etc., will be stored in separate scalars.) Append the
new line to the ”datebook” file by using a user–defined filehandle.

5B
1. In the ”datebook” file create a number of duplicate entries. Fred Fard-
barkle, for example, might appear five times, and Igor Chevsky three times,
etc. If you’re using the vi editor, just ”yank” and ”put” some of the entries.

Write a program that will assign the name of the ”datebook” file to a scalar
and check to see if the file exists. If it does exist, the program will check to
see if the file is readable and writeable. Use the die function to send any
errors to the screen. Also tell the user when the ”datebook” was last modi-
fied.

The program will read each line of the ”datebook” file giving each person a
10% raise in salary. If, however, the person appears more than once in the
file, (assume having the same first and last name means it is a duplicate) he
will be given a raise the first time, but if he appears again, he will be skipped
over. Send each line of output to a file called ”raise”. The ”raise” file should
not contain any person’s name more than once. It will also reflect the 10%
increase in pay.

Display on the screen the average salary for all the people in the ”datebook”
file. For duplicate entries, print the names of those who appeared in the file
more than once and how many times each appeared.

Basic Perl © 2006 Learning Enterprises, Inc.


120 Module5

Basic Perl © 2006 Learning Enterprises, Inc.


121

Module 6

Modularizing Perl
(Subroutines, Packages, Libraries)

6.1 Subroutines
• A subroutine statement is not executable, so can be anywhere in the script.
• Subroutine definitions are preceded by the keyword sub and the name of
the subroutine.
• Subroutines are invoked by prefixing the subroutine name with an amper-
sand, &. In Perl5, the ampersand is not necessary if the subroutine has a for-
ward reference or its name is followed by parentheses. A forward reference
is normally placed near the top of the program and consists of the keyword
sub and the name of the subroutine.
• Variables used in subroutines are global by default.
• Arguments, whether scalar values or arrays are passed call by reference.
• The @_ is a special array that handles arguments passed to the subroutine.
The @_ array is local to the subroutine. It’s values refer to the actual scalar
parameters. These values can be modified.
• Call by reference is achieved with a method called typeglob (aliasing).
• The local or my functions are used to turn on call–by–value and are highly
recommended by the Perl authors. The my function was introduced in Perl5
to ensure that variables are local only to the subroutine in which they are
created.
• The return value is the value of the last expression evaluated (either scalar
or array ). The return function can be used, but is not necessary, and a
bit slower.
• If the call to the subroutine is made part of an expression, the returned
value can be assigned to a variable, thus emulating a function call.
• To check if a subroutine exists, the defined function can be used.
Format:
Subroutine definition:
subroutine_name { statement; statement; }

Subroutine call:
&subroutine_name;
&subroutine_name(parameter1, parameter2, ... )

Basic Perl © 2006 Learning Enterprises, Inc.


122 Module 6

Forward reference (Perl5)


sub subroutine_name; # forward reference
subroutine_name; # call subroutine without &
sub subroutine_name { statements; } # subroutine definition

6.1.1 Defining and Calling a Subroutine

The following example demonstrates:


1. How to define a subroutine.
2. How to check that the subroutine has been defined.
3. How to call a subroutine.
4. The scope of variables in a subroutine.

Example 6.1
(The Script)
Script: perlsub
#!/usr/bin/perl
# Script: perl_sub2
1 # Variables used in subroutines are global by default.

2 sub bye { print “Bye $name\n”; $name = "Tom";} # subroutine definition

3 $name=“Ellie”;
4 print “Hello to you and yours!\n”;
5 &bye ; # Call subroutine
6 print “Out of the subroutine. Hello $name.\n" # $name is now Tom

(The Output)
4 Hello to you and yours!
2 Bye Ellie
6 Out of the subroutine. Hello Tom.

Basic Perl © 2006 Learning Enterprises, Inc.


123

6.1.2 Other Ways to Call a Subroutine

Forward Reference
• A forward reference announces to the compiler that the subroutine has
been defined somewhere in the program.
• The ampersand is not needed to call a subroutine if it has been forward ref-
erenced.

Example 6.2
#!/usr/bin/perl
1 sub bye; # Forward reference

$name="Ellie";
2 print "Hello $name.\n";

3 bye; # Call subroutine without the ampersand

4 sub bye{
5 print "Bye $name\n";
}
(Output)
2 Hello Ellie.
5 Bye Ellie

A Null Parameter List


• If the subroutine name is followed by parentheses (null parameter list), it
can also be called without the ampersand.

Example 6.3
#!/usr/bin/perl
1 $name="Ellie";
2 print "Hello $name.\n";

3 bye(); # Without parens or an ampersand, bye would be a bare word


# causing a warning message when -w is used.
4 sub bye{
5 print "Bye $name.\n";
}

Basic Perl © 2006 Learning Enterprises, Inc.


124 Module 6

6.2 Arguments
6.2.1 Passing by Reference

• Arrays and scalars are passed by reference by default.


• The @_ is a local array referencing the names of the formal arguments.
It’s values can be changed, thus changing the value of the actual parameters.
The elements of the @_ array are $_[0], $_[1], $_[2], etc.
• If a scalar variable is passed, it’s value is the first element of the @_ array,
$_[0].
• The split function will allow you to break the $_[0] into elements if it is a
string being split.

Example 6.4
The following example demonstrates:
1. How to pass arguments.
2. How to reference arguments in a subroutine with the @_ array.

(The Script )
#!/usr/bin/perl
# Script: perl_sub2
1 $first=“Steve”;
2 $last=“Blenheim”;
3 while(<>){
4 &greeting ( $first, $last ) if /[Ss]teve/;
5 }

6 sub greeting{
7 print “Welcome to the club, $_[0] $_[1]\n”;
8 print "@_";
}

(The Output)
$ perl_sub2 emp.names
7 Welcome to the club, Steve Blenheim
8 Steve Blenheim

Basic Perl © 2006 Learning Enterprises, Inc.


125

6.2.2 Making variables private with the my function


• my variables are lexically scoped; i.e. they are visible only from within the
block and any inner nested blocks from where they are declared.
• It is good practice to keep variables private if possible. The strict pragma,
is a special directive that tells the compiler to stop the compilation process
if it discovers any global variables.

Example 6.5
(The Script)
#!/usr/bin/perl

1 $friend="Louise"; # global variables


2 $pal="Danny";

3 print "$friend and $pal are global in scope.\n\n";

4 sub guests{
my $friend = "Pat";
my $pal = "Chris";
print "In the guests subroutine:
5 $friend and $pal are welcome guests!\n\n";
}

6 &guests;

7 print "After leaving the \"guests\" subroutine, \$friend is $friend


and \$pal is $pal\n ";
}

(The Output)
3 Louise and Danny are global in scope.

5 In the guests subroutine:


Pat and Chris are welcome guests!

7 After leaving the "guests" subroutine, $friend is Louise


and $pal is Danny

Example 6.6
#!/usr/bin/perl
# Default package is main
# Scriptname: strict_perl

Basic Perl © 2006 Learning Enterprises, Inc.


126 Module 6

1 use strict 'vars';


2 local @town = ( "Boston", "Chico", "Tampa" );
3 my $friend="Mary";

4 print " \$friend is $friend\n";

5 print " \@town is ", join(', ', @town), "\n";

(The Output)
2 Global symbol "town" requires explicit package name at strict_perl line 2.
5 Global symbol "town" requires explicit package name at strict_perl line 5.
Execution of package3 aborted due to compilation errors.

6.2.3 Passing by Value and the my Function


• The my function is used in Perl5 to replace the local function. It keeps the
variables local to the block and if in a subroutine, exclusively local to the
subroutine.

Example 6.7
(The Script )
#!/usr/bin/perl
# Script: perl_sub4
1 $first=Tom;
2 $last=Jones;
3 &greeting ( $first, $last ) ;

4 print “–––$fname–––\n”;
# Won’t print a value; $fname is local to the greeting function

5 sub greeting{
6 my ($fname, $lname) = @_ ; # $fname and $lname are local
7 print ”Welcome $fname!!\n”;
}

( The Output )
7 Welcome Tom!!
––––––

Basic Perl © 2006 Learning Enterprises, Inc.


127

6.3 The Return Statement


• The return value is the value of the last expression evaluated in the sub-
routine.
• The return statement is used to return from the subroutine at some point if
a certain condition occurs. Otherwise, using an explicit return is not neces-
sary.
• The returned value can be either a scalar or an array value.

Example 6.8
(The Script)
#!/usr/bin/perl
# Script: return_statement
1 sub MAX {
2 my($max) = shift(@_);
3 foreach $foo ( @_ ){
4 $max = $foo if $max < $foo;
5 print $max,”\n”;
6 }
7 print ”–––––––––––––––––––––––––––––\n”;
8 return $max;
}
9 sub MIN {
10 my($min) = pop( @_ );
11 foreach $foo ( @_ ) {
12 $min = $foo if $min > $foo;
13 print $min,”\n”;
14 }
15 print ”–––––––––––––––––––––––––––––\n”;
16 $min;
}

17 $biggest = &MAX ( 2, 3, 4, 10, 100, 1 );

18 $smallest= &MIN ( 200, 2, 12, 40, 2, 20 );


19 print “The biggest is $biggest and the smallest is $smallest.\n”;
#print $foo, $min, $max ; nothing prints; local variables.

(The Output)
3
4
10
100

Basic Perl © 2006 Learning Enterprises, Inc.


128 Module 6

100
–––––––––––––––––––––––––––––
20
2
2
2
2
–––––––––––––––––––––––––––––
The biggest is 100 and the smallest is 2.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

6.4 Packages
• Packages are used to create privacy. Variables in one package are not
known in another package (although they can be known).
• By default the main part of your program is called package “main”.
• All variables are global in the main package
• The package allows you to switch namespaces, so that variables in the
package are private, even if they have the same name somewhere outside
the package. A package contains symbols just as a directory contains files.
• The scope of the package is from from the declaration of the package to
the ending curly brace of the block following the declaration. Normally the
package is declared right before a subroutine or group of subroutine defini-
tions and there is one package per file.
• To reference a package (Perl5) variable in another package, the package
name is followed by two colons and the variable name, e.g.,

$package::variable.

Note that the dollar sign to indicate a scalar type variable precedes
the name of the package, not the variable name,
When referring to the main package, the name of the package can
be eliminated.

$::name is the same as


$main::name is the same as
$main’name

• Perl4 used an apostrophe to separate the package name from the variable,
e.g,.
$package’variable

Basic Perl © 2006 Learning Enterprises, Inc.


129

This method works in both Perl4 and Perl5.

• Perl5extends the notion of packages to that of modules. A module is a


package that is defined in a library file and is reusable. The files end with
a .pm extension.

6.5 The Symbol Table


• To compile a program, the compiler must keep track of all the names of
variables, filehandles, directory handles, formats, and subroutines that are
used.
• Perl stores the names of these symbols as keys in a hash table for each
package. The values associated with the keys are the corresponding values
called typeglobs. Perl actually creates separate pointers for each of the val-
ues represented by the same name. The name of the hash is the same name
as the package.
• Each package has its own symbol table.
• Any time you use a package declaration, you switch to the symbol table
for that package.
• The variables assigned with the my function are not accessible outside their
own package. They are not stored on the package symbol table, but are
stored on a private scratch pad created for each subroutine that is called.

Symbol Table Typeglobs Variable


$x (SCALAR)
x *x
@x (ARRAY)

y %x (HASH)

&x (SUB)
z

Basic Perl © 2006 Learning Enterprises, Inc.


130 Module 6

Each package has its own namespace (symbol table)

package main package friend package fun

$x=5; $x=5; $x=5;

Example 6.9
(The Script)
#!/bin/perl
# Package main
1 $name="Tom";
2 @name=qw(Joe Jeff Jan );

3 while(($key, $value) = each (%main::)){ # Look at main’s symbol table


4 print "$key:\t$value\n";
}
print "-" x 25, "\n";
5 my $pal = "Linda"; # Not on the symbol table
6 local $dude = "Ernie";

7 package friends;
8 print "Hello $main::dude, dude.\n";
9 print "My pal is $main::pal.\n";

(The Output)
4FileHandle:::*main::FileHandle
@: *main::@
name: *main::name
stdin: *main::stdin
STDIN: *main::STDIN
": *main::"
stdout: *main::stdout
STDOUT: *main::STDOUT
$: *main::$
_<perlmain.c: *main::_<perlmain.c
key: *main::key
ENV: *main::ENV

Basic Perl © 2006 Learning Enterprises, Inc.


131

_<package.dump: *main::_<package.dump
/: *main::/
ARGV: *main::ARGV
0: *main::0
STDERR: *main::STDERR
stderr: *main::stderr
: *main::
DynaLoader::: *main::DynaLoader
: *main::
main::: *main::main
DATA: *main::DATA
DB::: *main::DB
INC: *main::INC
value: *main::value
_: *main::_
-------------------------
12 Hello Ernie, dude.
13My pal is .

Example 6.10
The following example demonstrates
1. The declaration of a package
2. The scope of package variables,
3. How to reference variables in other packages using both Perl5 and Perl4.

(The Script)
#!/usr/bin/perl
# Script: package_example
1 $name=“Suzanne”; # defined in package mai
2 $num=100;
3 sub welcome {
4 package friend;
5 print “Who is your pal? ”;
6 chomp($name=<STDIN>);
7 print “Welcome $name!\n”;
8 print ”Where is $main::name?\n”;
9 print ”\$num is $num.\n”; # $num unknown in this package
10} # Package friend scope ends here
11 &welcome;
12print “Out of the subroutine. \$name is $name\n”;
13print “Bye ”,$friend::name,“\n”; # switch namespace to friend package
14print “Bye $name\n”; # Back in main package
15package birthday;
16$name="Beatrice";

Basic Perl © 2006 Learning Enterprises, Inc.


132 Module 6

17print ”\nHappy birthday, $name.\n”;


18print ”No, $main::name and $friend::name, it is not your birthday!\n”;
# Perl4 used the apostrophe, rather than the colon,
# to separate the package and variable; still works in Perl5.

( The Output )
5 Who is your pal? Tommy
7 Welcome Tommy!
8 Where is Suzanne?
9 $num is .
12 Out of subroutine, $name is Suzanne
13 Bye Tommy
14 Bye Suzanne

17 Happy Birthday, Beatrice!!


18 No, Suzanne and Tommy, it is not your birthday!

6.6 Using the strict Pragma in Packages


• A pragma is a compiler directive. It causes the program to abort and an
error message to be generated if the directive is not obeyed.
• The strict pragma allows you to prevent the use of global or local vari-
ables in a package . Only variables declared as "my" variables or those
whose names are fully qualified with the package name will be accepted or
a compilation error will occur. This ensures a higher level of privacy in the
package. To create global variables when strict is turned on, see Example
1.5.

Example 6.11
(The Script)
#!/usr/bin/perl
# Default package is main
1 use strict ’vars’; # Makes sure that global or local variables are outlawed

2 my @town = ( "Boston", "Chico", "Tampa" );


3 my $friend="Mary";

4 print "In main: \$friend is $friend\n";

5 {package boy; # package declaration


6 my $friend="Lizzy";
7 print "In boy \$friend is $friend\n";

Basic Perl © 2006 Learning Enterprises, Inc.


133

8 print "In boy \$main::friend is unknown", $main::friend, "\n";


9 print "In boy \@::town is unknown", @::town, "\n";
}
# Back in main
10print "1.In main: \$boy::friend is $boy::friend.\n";
11 print "2.In main: \@town is ", join(', ', @town), ".\n";
:
(The Output)
4 In main: $friend is Mary
7 In boy $friend is Lizzy
8 In boy $main::friend is unknown
9 In boy @::town is unknown
10 1.In main: $boy::friend is .
11 2.In main: @town is Boston, Chico, Tampa.

Example 6.12
(The Script)
#!/usr/bin/perl
1 # Default package is main
2 # Scriptname: strict_perl
3 use strict ;
4 @town = ( "Boston", "Chico", "Tampa" ); # Now didn’t I tell you?
5 my $friend="Mary";

6 print "\$friend is $friend\n";


7 print "\@town is ", join(', ', @town), "\n";

(The Output)
4 Global symbol "town" requires explicit package name at strict_perl line 4.
7 Global symbol "town" requires explicit package name at strict_perl line 14.
Execution of package3 aborted due to compilation errors.
------------------------------------------------------------------------

Basic Perl © 2006 Learning Enterprises, Inc.


134 Module 6

6.6.1 Declaring global Variables With our

• When strict is turned on, most variables must be declared.


• The vars pragma can be used to create a list of variable names for the
current package.
• The our directive is used to declare and assign values to global variables
as of 5.6 and is lexically scoped like my.

Example 6.13
#!/usr/bin/perl
package Presents;
use strict;
1 use vars qw( @toys ); # Old way, before "our"
@toys = qw( doll train legos puppet );
2 our @stores = qw( KMart Sears Wallmart ); # Perl 5.6+
$toys[0] = "Barbie\n";
print "@toys\n";

6.7 The Standard Perl Library


• The Perl distribution comes with a number of standard Perl library func-
tions and packages.
• The special @INC array contains the directory path where these functions
are located. The –l switch at the command line is an alternate way to include
library functions.
• The require function includes and executes a Perl function found in a sep-
arate file (like #include in C). In order for Perl to require a file, the file being
included must return a true value; it is customary to place a 1 at the end of
the file. The require function checks to make sure the library hasn’t already
been included. It searches the include path found in the @INC array.
The require is handled at run time.
• In Perl5 the notion of packages has been extended to the notion of mod-
ules. It’s now possible to load selected modules into your program rather
than a complete file. This is done by using the EXPORTER module and the
@EXPORTER array. It is also possible to create modules that are object ori-
ented. The object oriented modules are discussed in the Module 4.
• A module is a package that is defined in a library and is reusable. The
first letter of a module name is capitalized and the name ends in the exten-

Basic Perl © 2006 Learning Enterprises, Inc.


135

sion, .pm. The package used as a module has the same name as the .pm file.
For example, Addit.pm is the file and Addit is the package name, now called
module Addit.
• The use function imports modules into your program. The files that con-
tain the module normally end in .pm. The .pm suffix is not needed with use.
The no function lets you undefine a particular module used in your program.
The use function is handled at compile time.

Format:
require(”file.pl”);
require ”file.pl”;
require 5.6.1;1
require Socket.pm
require Socket; # also loads a .pm file
use Module;
no Module;

Note: To see the directories where your Perl libraries are distributed, type at
the command line:

perl -e ’print "@INC"’

6.7.1 Including Your Subroutines From another Directory


Steps:
1. Update the @INC array to include any subdirectories where subrou-
tines are located.
2. Use the require function to load in the desired subroutine by its name.
3. Call the subroutine with proper arguments if there are any.

Example 6.14
(The Script) Script: midterms
1 % cat midterms
2 #!/usr/bin/perl
3 unshift(@INC, ”./mylibs”);
4 require ”average.pl”;
5 print ”Enter your midterm scores.\n”;

1. If using 5.002 or any lower version than 5.003, complains "Perl 5.003 required--this is only version 5.002..."

Basic Perl © 2006 Learning Enterprises, Inc.


136 Module 6

6 @scores=split(’ ’, <STDIN>);
7 printf ”The average is %.1f.\n”, $average=&ave(@scores);

––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
8 % cd mylibs # Directory where library is located
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

9 % cat average.pl # File where subroutine is defined


10# Average a list of grades
11 sub ave {
my(@grades)=@_;
12 my($num_of_grades)=$#grades + 1;
13 foreach $grade ( @grades ){
14 $total=$total + $grade;
15 }
16 $total/$num_of_grades; # What gets returned
}
–––>1; # Make sure the file returns true or require will not succeed.

6.8 Using a Perl5 Module from the Standard Perl Library

6.8.1 Modules and .pm files


• A module is a file in a library function that behaves according to certain
set of conventions.
• The modules in the standard Perl library are suffixed with the .pm exten-
sion. They can also be found in subdirectories. For example, the module
Bigfloat.pm is found in a subdirectory called Math. To use a module found
in a subdirectory, the directory name is followed by two colons and the name
of the module; e.g. Math::Bigfloat.pm.
• When using one of the modules (those file ending in .pm) provided in the
standard Perl library, you must first make sure the @INC array contains the
full pathname to your library distribution and that you include the use func-
tion with the module name.

6.8.2 The use Function (Modules and Pragmas)

• The use function allows the correct importation of Perl modules and prag-
mas into your program at compile time.
• The use function will not import a module if the module’s filename does
not have the .pm extension.

Basic Perl © 2006 Learning Enterprises, Inc.


137

• The module is loaded with use at compile time, whereas with require it is
loaded at run time. Normally the @INC array is updated at run time. To
make sure that it is updated for the use function you can try any one of the
following:

Examples:
(In .login) setenv PERL5LIB "directory path"
(In .profile) PERL5LIB "directory path"; export PERL5LIB
(In perl script) BEGIN{ unshift(@INC, "directory path");}
(In perl script) use lib ("directory path");

• A pragma, spelled in lowercase letters, is a warning to the compiler that


your program should behave in a certain way and if it doesn’t the program
will abort. Some common pragmas are: lib, strict, subs, and diagnostics.
(The modules discussed in this chapter do not require any understanding
of objects. For a complete discussion on how to use the object oriented type
modules, see Chapter 11. )

Format:
use Module;
use Module(list);
use Directory::Module;
use pragma(list);
no pragma;

6.8.3 The Exporter Module and the @ISA Array


• The Exporter.pm module found in the standard Perl library supplies the
necessary semantics for modules to be able to export or import methods
(subroutines) and symbols.
• The @ISA array is a special array that contains a list of packages that will
be used by the current package. This is how Perl implements inheritance.
• The names listed in the @EXPORT array are by default switched into the
namespace of the program using the module. The user can specify those
symbols he wants to import by listing them as arguments to the use function.
• The names on the @EXPORT_OK array are only added to the user’s
namespace if requested.
• If the module is imported with use and parentheses are added to the mod-
ule name, as in use Module(), none of the symbols are imported.

Basic Perl © 2006 Learning Enterprises, Inc.


138 Module 6

TABLE 3.1 Exporting Symbols


The Exporting Module The Importing Module
File: TestModule.pm
package TestModule; use TestModule;
require Exporter; use TestModule qw( fun2 );
@ISA = qw(Exporter) ; use TestModule();
@EXPORT = qw(fun1, a, b);
@EXPORT_OK = qw(fun2, b, c);
@EXPORT_FAIL () Any symbols that cannot be exported are listed here.

6.8.4 Sample .pm file from Perl’s Standard Library

Example 6.15
1 package Carp;
# This package implements handy routines for modules that wish to throw
# exceptions outside of the current package.
2 @ISA = Exporter;
3 require Exporter;
4 @EXPORT = qw(confess croak carp);
5 sub longmess {
my $error = shift;
my $mess = ””;
my $i = 2;
my ($pack,$file,$line,$sub);
while (($pack,$file,$line,$sub) = caller($i++)) {
$mess .= ”\t$sub ” if $error eq ”called”;
$mess .= ”$error at $file line $line\n”;
$error = ”called”;
}
$mess || $error;
}
6 sub shortmess {
my $error = shift;
my ($curpack) = caller(1);
my $i = 2;
my ($pack,$file,$line,$sub);
while (($pack,$file,$line,$sub) = caller($i++)) {
return ”$error at $file line $line\n” if $pack ne $curpack;
}
longmess $error;
}

Basic Perl © 2006 Learning Enterprises, Inc.


139

7 sub confess { die longmess @_; }


8 sub croak { die shortmess @_; }
9 sub carp { warn shortmess @_; }
10 # sub cluck { warn longmess @_}2

6.8.5 Using Modules from the Standard Perl LIbrary


In the following example the croak function is called with an error message
as its argument. The program will die if the value of $number is not in the
range between 0 and 100. The error message reports the line where the pro-
gram died as well as the name of the package, subroutine name, and the
number of the line where the subroutine was invoked.

If you create a subroutine by the same name as one of the library routines,
listed as arguments to Carp, your subroutine will take precedence. If you try
to call one of the subroutines from Carp.pm that are not listed for import,
you will get an error message. In order, in the following example, to call
confess or carp from Carp.pm, their names must be fully qualified,
Carp::confess or Carp::carp.

Example 6.16
#!/bin/perl
1use Carp qw(croak); # Import the croak function. If you want to use either
# confess or croak, must fully qualify the name; e.g. Carp::confess.
2print "Give me a grade: ";
$grade = <STDIN>;
3try($grade); # Call subroutine

4sub try{
5 my ($number)=@_;
6 croak "Illegal value: " if $number < 0 || $number > 100;
}

(The Output)
2Give me a grade: 200
6Illegal value: at expire line 13
main::try called at expire line 8

2. This new function, called cluck, has been added to the Carp.pm module; in fact, Carp.pm has been re-writ-
ten with embedded documentation. Go to the standard Perl library to see the new look.

Basic Perl © 2006 Learning Enterprises, Inc.


140 Module 6

6.8.6 Using Perl to Create Your Own Module

The following example illustrates how to create a module in a separate file.

Example 6.17
(At The Command Line)
% cat Module/Me.pm
1 package Me;
use strict;
2 require 5.6.0; # Make sure this is Perl5
3 require Exporter; # Exporter.pm allows modules to be imported
4 our @ISA=qw(Exporter); # ISA is a list of packages to import
5 our @EXPORT=qw(hello goodbye ); # list of subroutines to export
6 sub hello { my($name)=shift;
print ”Hi there, $name.\n” };
7 sub goodbye { my($name)=shift;
print ”Good bye $name.\n”;}
8 sub do_nothing { print ”Didn’t print anything. Not in EXPORT list\n”; }
1;
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
% cat main.perl
#!/usr/bin/perl
9 use lib (”/home/ellie/Module”); # Update @INC array at compile time
10use Me; # Import package
11&hello (’Danie’l);
12&goodbye (’Steve’);
13&do_nothing; # This was not on the Export list in Me.pm so cannot be imported

(The Output)
11 Hi there, Daniel.
12 Good–bye Steve.
13 Undefined subroutine &main::do_nothing

Basic Perl © 2006 Learning Enterprises, Inc.


141

Exercise 6

1. Write a program called ”tripper” that will ask the user the number of
miles he has driven and the amount of gas he used. In the tripper script,
write a subroutine called mileage that will calculate and return the user’s
mileage (miles per gallon). The number of miles driven and the amount of
gas used will be passed as arguments. All variables should be my variables.
Print the results.

2. Hotels are often rated by stars where a 5 star hotel may have a king size
bed, a kitchen, and 2 tv's, while a 1 star hotel may have cockroaches and a
leaky roof. Write a subroutine called, "printstar" that will produce a histo-
gram to show the star rating for hotels shown in the following hash. The
"printstar" function will be given two parameters, the name of the hotel and
the number of its star rating. (Hint: sort the hash keys into an array. Use a
loop to iterate through the keys, calling the printstar function for each iter-
ation. )

%hotels=("Hilton" => "5",


"Regent" => "5",
"Days Inn" => "3",
"Best Western" => "4",
"Rancho El Cheapo" => "1",
"Motel 6" => "2",
);
OUTPUT:

Hotel Category
------------------------------------------
Best Western |**** |
Days Inn |*** |
Hilton |***** |
Motel 6 |** |
Rancho El Cheapo |* |
Regent |***** |
-----------------------------------------
(Note that the hotel names have been sorted ).

Basic Perl © 2006 Learning Enterprises, Inc.


142 Module 6

Exercise 6B
1a. Create a module called "Checking.pm"

Initialize a variable called "$balance" to 0.


Create four subroutines in package Checking:
a. get_balance
b. deposit
c. withdraw
d. exit

b. Create a script that will act as the user interface; i.e. a script that will
"use" the Checking.pm module. This script will be called myATM.plx.
It will contain a "here document" that will produce the following menu:

1) Deposit
2) Withdraw
3) Current Balance
4) Exit

Ask the user to select one of the menu items. Until menu item #4 is
selected, the program will go into a loop to re-display the menu and wait for
him to select another transaction. The subroutines will be called by quali-
fying the subroutine name with the name of the Checking package; e.g.
Checking::deposit().

. If the user chooses number 4, when the program exits, print today’s date
and the current balance to a file called "register".

2. Re-write the Checking module so that it gets the balance from the file
"register" if the file exists; otherwise it will start at a zero balance. Each
time the program exits, save the current balance, the time and date in the
"register" file.

3. Can you create more than one account, e.g. an account for three differ-
ent users?

Basic Perl © 2006 Learning Enterprises, Inc.


143

Exercise 6c
1a.Create an EXPORT list in the Checking module which will consist of all
the names that will be imported my the user of the module. (The names will
be the names of the subroutines.)

b. In the myATM.plx file, use the Checking module, and remove the colon
syntax from each of the function calls that are listed in the EXPORT list in
Checking.pm.

c. Move the Checking.pm module into its own library (directory) and reset
the @INC array in the myATM file to include this new libary.

b. Download the "Switch.pm" module from CPAN (Use ppm. If you have
ActiveState. It’s easy) Use this module in your Checking.pm file. After the
user selects an entry from the menu, use the switch mechanism provided by
the Switch.pm module rather than the if/elsif construct to check the user’s
selections.

Basic Perl © 2006 Learning Enterprises, Inc.


144 Module 6

Basic Perl © 2006 Learning Enterprises, Inc.


145

Module 7
References
7.9 Hard References (Pointers)
• Perl5 references can also be called pointers. If you know C, Perl pointers
will be easy to understand.
• A pointer is a scalar that contains the address of a variable. When a
backslash precedes the funny character that represents the data type of
a variable, the address of that variable is assigned to a scalar.
• A scalar that holds the address can be called a pointer.
• A pointer contains the address of a scalar, array, associative array, or
subroutine e.g, $ref=\$n says that $ref is a pointer to a scalar $n.
$ref=\@n says that $ref is a pointer to the array @n.
• A pointer can be dereferenced, i.e., the value stored at that address can
be fetched by prefixing the pointer variable, a scalar, with the funny symbol
for the variable type it references e.g., @$pointer dereferences an array;
$$pointer dereferences a scalar.
Example 7.18
(The Script)
#!/usr/bin/perl
1 @toys=qw(Barbie Elmo Thomas);
2 $num = @toys; # Get the number of toys
3 %games = ( "Nintendo"=> "Wii",
"Sony"=>"PlayStation 3",
"Microsoft" => "XBox 360");

4 $ref1 = \$num; # Pointer to scalar


5 $ref2 = \@toys; # Pointer to array
6 $ref3 = \%games; # Pointer to hash

7 print "There are $$ref1 toys.\n";

8 print "They are @$ref2\n";

9 print "Willie's favorite toy is $ref2->[2]\n";


10print "Debbie's favorite toy is $ref2->[0]\n";

11 while(($key, $value) = each(%$ref3)){


print "$key => $value\n";
}
12print qq(They waited in line for a $ref3->{"Nintendo"}.\n);

Perl Programming Copyright 2008, Learning Enterprises, Inc.


146 Module 7

(The Output)
7 There are 3 toys.
8 They are Barbie Elmo Thomas
9 Willie's favorite toy is Thomas
10Debbie's favorite toy is Barbie
11 Microsoft => XBox 360
Sony => PlayStation 3
Nintendo => Wii

12They waited in line for a Wii.

3
SCALAR(0x182efa8ref)
ref1 $num
0x4588

ARRAY(Ox182ef2498) Barbie Elmo Thomas


$ref2 @toys
0xa6998

7.10 Anonymous Variables and References


• It is not necessary to name a variable to create a reference to it.
• If a variable or subroutine has no name, it is anonymous.
• If an anonymous variable (or subroutine) is assigned to a scalar,
the scalar is a reference to that variable (or subroutine).
• When working with Perl5 objects, anonymous references are used. The
arrow (infix) operator is used to make dereferencing arrays and hashes eas-
ier to manage.

Perl Programming Copyright Learning Enterprise, Inc. 2008


147

7.10.1 Anonymous Array

Example 7.19
(The Script)
#!/usr/bin/perl
# Script: anon_arr_hash
1 $arrayref = [ ’Woody’, ’Buzz’, ’Bo’, ’Mr. Potato Head’ ];
2 print $arrayref–>[0], ”\n”; # or $$arrayref[0]
3 print "The number of elements in the array are ", $#{$arrayref} + 1, ".\n";

(The Output)
2 Woody
3 The number of elements in the array are 4.

7.10.2 Anonymous Hash

Example 7.20
(The Script)
#!/usr/bin/perl
1 $hashref = { "Name"=>”Woody”, "Type"=>”Cowboy”};
2 print $hashref–>{"Name"}, ”\n\n”; # or $$hashref{Name}
3 print keys (%$hashref);
print ”\n”;

(The Output)
2 Woody
3 NameType

7.10.3 Nested Data Structures and Pointers

Example 7.21
(The Script)
# Scriptname: anon_toys
1 $hashref = { "ToyName" => "Lego",
2 "Shape" => [ "Square", "Triangle", "Rectangle" ],
3 "Color" => [ "Red", "Green", "Blue", "Yellow" ],
};
# Shape and Color are keys. The associated values are anonymous lists.
4 print "The toy is a $hashref->{ToyName}, it is a $hashref->{Shape}->[0]
shape, and its color is $hashref->{Color}->[2].\n";

Perl Programming Copyright 2008, Learning Enterprises, Inc.


148 Module 7

(The Output)
4 The toy is a Lego, it is a Square shape, and its color is Blue.

Example 7.22
(The Script)
1 $ptr = { "Teacher"=>{"Subjects"=>[ qw(Science Math PE) ]},
"Musician"=>{"Instruments"=>[ qw(piano flute harp)]},
};
# Teacher and Musician are keys. The values consist of nested hashes.
2 print $ptr->{"Teacher"}->{"Subjects"}->[0],"\n";
3 print "@{$ptr->{Musician}->{Instruments}}\n";

(Output)
2 Science
3 piano flute harp

7.10.4 Anonymous Subroutine

Example 7.23
(The Script)
1 $subref = sub { print @_ ; };
2 $subref->(’a’,’b’,’c’); #call the subroutine
print ”\n”;

(The Output)
1 abc

Perl Programming Copyright Learning Enterprise, Inc. 2008


149

7.10.5 Reference to Multi-dimensional Array

Example 7.24
(The Script)
#!/usr/bin/perl
# Two dimensional array
1 $matrix = [ [ 0, 2, 4],
[ 4, 1, 32 ],
[ 12, 15, 17 ]];
2 print "Row 3 column 2 is $matrix->[2]->[1].\n";
3 for($x=0;$x<3;$x++){
for($y=0;$y<3;$y++){
4 print "$matrix->[$x]->[$y] ";
}
print "\n";
}

(The Output)
2 Row 3 column 2 is 15.
4 024
4 4 1 32
4 12 15 17

7.10.6 Pointers and Subroutines

Example 7.25
(The Script)
#!/usr/bin/perl
1 sub gifts;
2 $num = 3;
3 @toys = qw( Buzzlightyear Woody Thomas );
4 gifts( \$num, \@toys ); # passing by reference
5 sub gifts {
6 my( $n, $t) = @_; # localizing the reference with my
7 print ”There are $$n gifts: ”;
8 print ”@$t\n”;
}

(The Output)
7 There are 3 gifts: Buzzlightyear Woody Thomas

Perl Programming Copyright 2008, Learning Enterprises, Inc.


150 Module 7

7.10.7 The ref Function


The ref function returns the type of the variable that the reference points
to e.g., ref returns SCALAR if the reference points to a scalar type or
ARRAY if it refers to an array, etc. If the reference doesn’t really exist, ref
returns undefined.

Values returned can be:


SCALAR
ARRAY
HASH
CODE
GLOB
REF

Example 7.26
(The Script)
#!/usr/bin/perl
1 sub gifts; # forward reference
2 $num = 3;
3 $junk = ”xxx”;
4 @toys = qw( Buzzlightyear Woody Thomas );
5 gifts( \$num, \@toys, $junk ); # $junk is not a reference

6 sub gifts {
7 my( $n, $t, $j) = @_;
8 print ”\$n is a reference.\n” if ref($n);
9 print ”\$t is a reference.\n” if ref($t);
10 print ”\$j is a reference.\n” if ref($j); # not a reference; nothing prints
11 printf”\$t is a reference to an %s.\n”, ref($t);
}

(The Output)
8 $n is a reference.
9 $t is a reference.
11 $t is a reference to an ARRAY.

Perl Programming Copyright Learning Enterprise, Inc. 2008


151

7.11 Using Data::Dumper

perldoc Data::Dumber
NAME
Data::Dumper - stringified perl data structures, suitable for both
printing and "eval"

SYNOPSIS
use Data::Dumper;

# simple procedural interface


print Dumper($foo, $bar);

# extended usage with names


print Data::Dumper->Dump([$foo, $bar], [qw(foo *ary)]);

# configuration variables
{
local $Data::Dumper::Purity = 1;
eval Data::Dumper->Dump([$foo, $bar], [qw(foo *ary)]);
}

# OO usage
$d = Data::Dumper->new([$foo, $bar], [qw(foo *ary)]);
...
print $d->Dump;
...
$d->Purity(1)->Terse(1)->Deepcopy(1);
eval $d->Dump;

Perl Programming Copyright 2008, Learning Enterprises, Inc.


152 Module 7

Example 4.27
1 use Data::Dumper;
2 my $petref = [
3 { name=>"Rover",
type=>"dog",
owner=>"Mr. Jones",
},
{ name=>"Sylvester",
type=>"cat",
owner=>"Mrs. Black",
},
{ name=>"Tweetie",
type=>"bird",
owner=>"Ms. Singer",
},
];

3 $Data::Dumper::Indent=1;
4 print Dumper($petref);

(Output)
$VAR1 = [
{
'owner' => 'Mr. Jones',
'name' => 'Rover',
'type' => 'dog'
},
{
'owner' => 'Mrs. Black',
'name' => 'Sylvester',
'type' => 'cat'
},
{
'owner' => 'Ms. Singer',
'name' => 'Tweetie',
'type' => 'bird'
}
];

Perl Programming Copyright Learning Enterprise, Inc. 2008


153

Example 7.28
1 use Data::Dumper;
2 open(DB, "datebook") or die "Can't open file: $!\n";
3
4 # Create an array of hashes, and a reference to the array
5
6 while (<DB>) {
7 ($h{name},$h{phone},$h{address},$h{birthday},$h{salary}) = split(":",$_);
8 push(@aofh,{%h}) unless $_ =~ /^ *$/; # Create an array of hashes
9 }
10
11 foreach $record (@aofh){
12 foreach $field (values %$record){
13 print "$field\n";
14 }
15 }
16
17 print Dumper(\@aofh);

(Sample output)

Steve Blenheim
95 Latham Lane, Easton, PA 83755
238-923-7366
11/12/56
20300

Betty Boop
635 Cutesy Lane, Hollywood, CA 91464
245-836-8357
6/23/23
14500

Igor Chevsky
3567 Populus Place, Caldwell, NJ 23875
385-375-8395
6/18/68
23400
--------------------Data Dumper Output----------------
$VAR1 = [
{
'name' => 'Steve Blenheim',
'address' => '95 Latham Lane, Easton, PA 83755',
'phone' => '238-923-7366',

Perl Programming Copyright 2008, Learning Enterprises, Inc.


154 Module 7

'birthday' => '11/12/56',


'salary' => '20300
'
},
{
'name' => 'Betty Boop',
'address' => '635 Cutesy Lane, Hollywood, CA 91464',
'phone' => '245-836-8357',
'birthday' => '6/23/23',
'salary' => '14500
'
},
{
'name' => 'Igor Chevsky',
'address' => '3567 Populus Place, Caldwell, NJ 23875',
'phone' => '385-375-8395',
'birthday' => '6/18/68',
'salary' => '23400
'
},

Exercise 7
What’s the Point?
1. Create two arrays: the first one an array of numbers
10 floating point numbers, and the second array containing
numbers integers between between 1 and 150.
Send the addresses of these arrays to a function called ave()
that will return the average of all the numbers. Print with
average with a precision of one decimal place.

2. Create a hash named employees with the following three


keys:
Name
Ssn
Salary

The values will be assigned as undefined. For example:


Name => undef,

Perl Programming Copyright Learning Enterprise, Inc. 2008


155

a. Create a reference to the hash.


b. Assign values to each of the keys using the reference.
c. Print the keys and values of the hash using the built-in each function and
the reference.
d. Print the value of the reference i.e., what the reference variable contains,
not what it points to.

2. Rewrite the last exercise so that the hash is anonymous and assign the
anonymous hash to a reference. Delete one of the keys from the hash using
the reference ( use the delete function).

3. Write a program that will contain the following structure:

$student = { Name => undef,


SSN => undef,
Friends => [],
Grades => { Science => [],
Math => [],
English => [],
}
};
Use the pointer to assign and display output resembling the following;

Name is John Smith.


Social Security Number is 510-223-1232.
Friends are Tom, Bert, Nick.
Grades are:
Science--100, 83, 77
Math--90, 89, 85
English--76, 77, 65

4. Use the Data::Dumper module to display your structure.

Perl Programming Copyright 2008, Learning Enterprises, Inc.


156 Module 7

Perl Programming Copyright Learning Enterprise, Inc. 2008


157

Module 8
Perl Objects
8.1 Object Oriented Perl
• Object oriented languages, such as C++ and Java, bundle up data into a
variable and call it an object. The object’s data describes the properties, also
called attributes. The object’s data is normally kept private. Messages are
sent to the object through special subroutines called methods. These sub-
routines provide "methods" to get at the data. The methods are normally
public. The only way that a user of the program should access the data is
through these methods.
• The data and the methods are packaged up into a data structure called a
class. A Perl package will function as a class when using the object oriented
approach. The object oriented approach is often compared to real life situa-
tions. For example, you are a member of the mammal class, Queen Eliza-
beth is in a high social class, and a Ford Explorer is in a class of cars called
sports vehicles.
• The published interface is the written documentation describing how the
programmer should use a class (e.g. what arguments will be passed to a
method ). The interface should not change, even if something in the class is
changed.
• In Perl modules are special packages (in a .pm file) that are defined in a
library. A module may also function as a class.
• Perl does not use keywords such as private, public, or protected.
• A Perl class is a package that combines data and subroutines. The subrou-
tines are called methods. These methods are used to manipulate the data in
the class, e.g., they allow the data to be retrieved, displayed, updated, etc.
• When functioning as a class, double colons (scope operator) are not
required when calling a method from another package.
• The data is normally stored in an anonymous hash. The address of the
anonymous hash is assigned to a reference. The reference is made private
to the class with the my function.The bless function makes sure that an
object belongs to a specific class by tagging the object with an internal
pointer.
• An object and all access to the object are managed by methods. 1

Perl Programming Copyright 2008, Learning Enterprises, Inc.


158 Module 5

• A module can export its symbols (variables and subroutines) to other pro-
grams with the Exporter module. A module can list the symbols it is willing
to export in two special arrays, @EXPORT and @EXPORT_OK.
• When used as a class, a module doesn’t need to explicitly export its sym-
bols. Perl handles all the details of exportation and importation.
• Inheritance is when a new class is derived from an existing (base) class.
This is accomplished in Perl by putting the "base" class names in the special
@ISA array.
• Modules can provide both a procedural interface and an object oriented
interface; that is, the module can contain exported subroutines as well as
objects and methods.

8.2 OOP Terms


TABLE 8.1 Key OOP words
Word Perl Meaning
Data encapsulation hiding data and subroutines from the user in a package
Inheritance the reuse of code usually from a library where a package inherits from other
packages
Polymorphism literally "many forms" but the ability to extend the functionality of a class
Object a referenced type that knows what class it belongs to
Method a subroutine that manipulates objects.
Class a package that contains objects and methods.
Constructor a method that creates and initializes an object.
Destructor a method that destroys an object.

1. Unlike most object-oriented languages, Perl does not enforce encapsulation of data; i.e. you can directly
access the object’s data, even though it is against all the cardinal rules of oop to do so.

Perl Programming © 2008 Learning Enterprises, Inc.


159

8.3 Classes
• A Perl class is a package containing variables to represent the data and
special subroutines called methods to act on the data.
• A class normally consists of:
1. The data (also called properties or attributes) that belongs in the
class.
2. Subroutines that know how to access and manipulate the data in
the class.
• Because it is a package, a class has its own symbol table.
• To keep variables private, the my function is used. The my variables exist
only within the innermost enclosing block, subroutine, eval or file. The my
variables cannot be accessed from another package by using the double
colon or single apostrophe.

Package A Package B

symbol table symbol table

$x $x

8.4 Objects
• An object in Perl is created with a hard reference (pointer).
• An object and its attributes are described in a package; when the object is
created it takes up a region in memory; it is instantiated.
• A reference is normally assigned the address of an anonymous hash. The
hash will contain the data members of the object (similar to a C struct).

Perl Programming Copyright 2008, Learning Enterprises, Inc.


160 Module 5

• In addition to storing the address of a hash, an object (anonymous "thing")


must know what package it belongs to. This is done by creating the refer-
ence and then "blessing" it into a package.
• The bless function blesses the "thing" being referenced into the package,
not the reference itself. It creates an internal pointer to track what package
the "thing" (object) belongs to.
• The object is the "thing" (usually a hash) that was blessed into the class,
(package).
• If the package is not listed as the second argument, the bless function
assumes the current package. It returns a reference to the "blessed" object.
• An object can be blessed into one class and then reblessed into another and
then another, etc.
• Procedural languages are action oriented; OO languages are object ori-
ented.

What makes a Class? The Package (Class)

sub new{
Attributes/data Constructor method
Bless the object
} (Create the object)

sub setdata{ }
Access methods
( store and fetch
data from the object)
sub getdata{ }

Perl Programming © 2008 Learning Enterprises, Inc.


161

8.4.1 The bless Function

• The bless function blesses the object being referenced2 into the pack-
age, not the reference itself.

Format:
bless REFERENCE, CLASSNAME;
bless REFERENCE;
return REFERENCE;

Example:
$reference = {};
bless( $reference, $class);
return $reference;
or
return bless($reference, $class);

Example 8.1
(The Script)
1 package Employee; # Package declaration

2 my $ref={ name=>"Tom", # Anonymous hash; the data for the package


salary=>25000, # Describes what the object will look like
};
3 bless($ref, Employee); # The hash referenced by $ref is blessed into the
# package; i.e. an internal pointer is created to track
# the package it belongs to.
4 print "The bless function tags the hash with its package name.\n";
5 print "The value of \$ref is: $ref.\n";
6 print "The ref function returns the package name:", ref($ref).\n";
7 print "The employee’s name is $ref->{name}.\n"; # Use the reference

(The Output)
4 The bless function tags the hash with its package name.
5 The value of \$ref is: Employee=HASH(Ox5a08a8).
6 The ref function returns the package name: Employee.
7 The employee’s name is Tom.

2. The object being referenced is called a "referent".

Perl Programming Copyright 2008, Learning Enterprises, Inc.


162 Module 5

8.5 Methods
• A method is a subroutine that operates on an object.
• It is a special subroutine that belongs to a class and expects its first argu-
ment to be a package name or a reference to an object. Otherwise, it looks
like any other subroutine.
• A method is used primarily to assign or change the data in an object or to
retrieve data from an object.
• There are two types of methods:

class ( or static) methods


instance (or virtual) methods

• The class method expects a class name as its first argument. It


affects the class as a whole; e.g. it can create an object or act on a
group of objects and doesn’t require an instance of the object. In
object oriented programs, a constructor function is a class method
used to create an object. In Perl this method is
commonly called "new", although you can call it anything you want.

• The instance method expects an object reference as its first argu-


ment. It manipulates an object. This reference is often called "$this
or "$self" in Perl scripts. Object oriented programs often use instance
methods (also called access functions) to control the way data is
assigned, modified, and retrieved.

A Class

Private Public Methods

Data to access

private data

Perl Programming © 2008 Learning Enterprises, Inc.


163

8.5.1 Invoking Methods.


A method can be invoked in two ways: class method invocation or
instance method invocation. There are two types of syntax for each method
call: the indirect syntax and the object oriented syntax.

• Class method invocation:


(Assume the method name is called "new" and the object’s reference is
called "$ref")

1) $ref = new class ( list of arguments ); # indirect syntax


2) $ref = class->new( list of arguments ); #object oriented syntax

If the class is called "Employee", Perl translates that to:

$ref = Employee::new(Employee, $args);

• Instance method invocation:


(Assume the method name is called "display" and the object reference is
called "$ref")

1) display $ref ( list of arguments ); # indirect syntax


2) $ref->display( list of arguments ); #object oriented syntax

The first example for each method is called the indirect syntax; the sec-
ond example, using the arrow operator, is called the object oriented syntax.
When Perl sees one of the above methods being invoked, it knows what
class the object belongs to because the object was blessed ( an internal
pointer is tracking where it is).3
If you call either:
display $ref ($args);
or
$ref->display($args);
and $ref points to an object in a package (class) called "Employee":
Perl translates that to:
Employee::display($ref, $args);

3. The ability of Perl to call the approprate module’s function is called run-time binding. (Advance Perl Pro-
gramming , O’Reilly & Associates, 1997, ISBN: 1-56592-220-4).

Perl Programming Copyright 2008, Learning Enterprises, Inc.


164 Module 5

ClassExample.pm (The file) The Package (Class)

package ClassExample;
sub new{
my $class=shift; Constructor method
my $ref = {};
bless ( $ref, $class); (Create the object)
return $ref;
}
sub setdata {
my $self=shift; Access methods
$self->{key}=value; ( store and fetch
} data from the object)

sub getdata {
my $self = shift;
print $self->{key};
}
1;

User of the Class


#!/usr/bin/perl
# package is main
use ClassExample;
$ref_to_obj = ClassExample -> new (args);
$ref_to_obj -> setdata(args);
$ref_to_obj -> getdata(args);

Perl Programming © 2008 Learning Enterprises, Inc.


165

8.5.2 The "new" Class Method


• The primary job of the "new" class method is to create and initialize an
object. A method that creates an object is called a constructor in OOP
lingo. In Perl there is no special syntax for a constructor.
• The new method is called a class method since its first argument is the
name of the class to which it belongs. It is a subroutine that blesses a refer-
enced "thing" into a class and returns the reference. Since the subroutine
blesses something, it can now be called a method and the "thing" it blesses
is called an object. The package is called a class.

Example 8.2
(The Module: Employee.pm)
1 package Employee; # class

2 sub new { # class method called a constructor


3 my $class = shift;
4 my $worker={ Name=>undef, # Attributes of the object
Salary=>undef, #Values will be assigned later
};
5 bless($worker, $class); # $worker is now references an object in this
# class
6 return $worker; #The reference to the object is returned
}
1;
----------------------------------------
(The User Script)
#!/usr/bin/perl
7 use Employee;
8 $empref = Employee->new(); # call the new method and create the object
9 # my $empref = new Employee; another way to call the new method
10 $empref->{Name}="Dan Savage"; # Use the object
$empref->{Salary}=75000;
11 print "\$empref in main belongs to class ", ref($empref),".\n";
12 print "Name is $empref->{Name}.\n";
13 print "Salary is $empref->{Salary}.\n";

(The Output)
11 $empref in main belongs to class Employee.
12 Name is Dan Savage.
13 Salary is 75000.

Perl Programming Copyright 2008, Learning Enterprises, Inc.


166 Module 5

8.5.3 Instance Methods


• Instance methods imply that there must be an object to work on. The
object is "instantiated" when the constructor method is called.
• An instance method takes an object as its argument. It is used to access
the object. In object oriented programs, these methods are the only way that
the private data should be accessed.
• In Perl, the package itself offers a certain level of privacy. The use of the
my function on variables keeps the scope of those variables local to the
package.

Example 8.3
(The Module: Employee.pm)
1 package Employee;
2 sub new{ # Class/Static method
3 my $class = shift;
4 my $worker={}; # Anonymous and empty hash
5 bless($worker, $class);
6 return $worker;
}
7 sub set_name{ # Instance method used to access object’s data
8 my $self = shift;
9 print "\$self is a class ", ref($self)," reference.\n";
10 $self->{Name} = shift;
}
11 sub get_name { # Instance method
12 my $self = shift; # The object reference is the first argument
13 print "The worker is ", $self->{Name},"\n";
}1;
------------------------------------------------------------------------------------------------------------
(The User Script)
#!/usr/bin/perl
14 use Employee;
15 my $emp = Employee->new(); # Call class method and create the object
16 $emp->set_name("Tom Savage"); # Object oriented syntax The object
# set_name $emp("Tom Savage"); # Call instance method after the blessing
17 $emp->get_name; # Object oriented syntax Employee
is tagged with its
class, Employee.
# get_name $emp; # Call instance method
0x5a08a8
(The Output)
0x5a08a8 $empref points to the object
9 $self is a class Employee reference.
13 The worker is Tom Savage $empref

Perl Programming © 2008 Learning Enterprises, Inc.


167

8.5.4 Passing Parameters to Constructor Methods


• Any arguments passed to a constructor method are called instance vari-
ables. They come into existence when an object is created or instantiated.
• Instance variables are used to initialize an object when it is created. In
this way each time an object is created, it can be customized. Either an anon-
ymous hash or an anonymous array are commonly used to hold the instance
variables. In the following example the object "has a" or "contains a" name
and a salary.

Example 8.4
(The Module:Employee.pm)
#!/bin/perl
1 package Employee;
2 sub new{ # Constructor method
3 my $class = shift;
4 my ($name, $salary) = @_; # Instance variables

5 my $worker={’Name’=>$name,
’Salary’=>$salary,
# Instance variables to initialize the object
};
6 bless($worker, $class);
7 return $worker;
}
8 sub display { # An instance method
9 my $self = shift; # The name of the object is passed
10 while( ($key, $value)=each %$self
){ print "$key: $value \n";}
}
1;
---------------------------------------------------------------------------------------------
#!/usr/bin/perl
11 use Employee;
# Documentation explaining how to use the employee package is called the
# public interface. It tells the programmer how to use the class.
# To create an Employee object requires two arguments, a name and salary.
# Invoking constructor--two ways
# my $emp1 = new Employee("Tom Savage", 250000);
12 my $emp1 = Employee->new("Tom Savage", 250000);
13 my $emp2 = Employee->new("Devin Quigley", 55000);
# Two objects have been created.
# Invoking the methods--two ways

Perl Programming Copyright 2008, Learning Enterprises, Inc.


168 Module 5

14 # display $emp1; # The indirect object syntax


15 $emp1->display; # The object oriented syntax
16 $emp2->display;
17 print "$emp1, $emp2\n";

(The Output)
15 Name: Tom Savage
Salary: 250000
16 Name: Devin Quigley
Salary: 55000
17 Employee=HASH(0x9d450), Employee=HASH(0xa454c)

8.5.5 Passing Parameters to Instance Methods


• The first argument to an instance method is the name of the object refer-
ence.
• This value is typically shifted from the @_ array and stored in a my vari-
able called $self or $this, though it doesn’t matter what you call the variable.
• The remaining arguments are then processed as they are in any regular
subroutine.
• A Perl convention is to precede the attribute name with an underscore to
indicate that it is internal to the class.

Example 8.5
# Program to demonstrate passing arguments to an instance method.
# When the method is called the user can select what he wants returned.
1 package Employee;
2 sub new{ # Constructor
my $class = shift;
my ($name, $salary, $extension) = @_; #Instance variables
my $worker = {_Name=>$name,
_Salary=>$salary,
_Extension=>$extension,
};
return bless($worker,$class);
}
3 sub display { # Instance method
4 my $self = shift; # Object reference is the first argument
5 foreach $choice ( @__){
6 print "$choice: $self->{$choice}\n";
}
}
-------------------------------------------------------------------------------------------------

Perl Programming © 2008 Learning Enterprises, Inc.


169

#!/usr/bin/perl
7 use Employee;
8 $emp = Employee-> new("Tom Savage", 250000, 5433);
9 $emp->display ("_Name", "_Extension"); # Passing arguments to instance
# method

(Output)
6 _Name: Tom Savage
6 _Extension: 5433

8.6 Destructors and Garbage Collection


• Perl keeps track of the number of references to an object and when the
count reaches 0, the object is automatically destroyed.
• When your program exits, Perl handles the garbage collection by destroy-
ing every object associated with the program.
• You can define a DESTROY method in your program to get control of the
object just before it goes away.
• The delete function is used to remove a hash key and value from a speci-
fied hash.
• The exists function returns true if the specified hash key exists in the hash.

Example 8.6
(The Module: Employee.pm)
1 package Employee;
sub new{
my $class = shift;
$worker={_Name=>undef,
_Salary=>undef,
};
2 bless($worker, $class);
return $worker; }
3 sub DESTROY{ # Getting control of an object before it is destroyed
my $self = shift;
4 print "Hash Name entry still exists.\n" if exists $self->{_Name};
5 delete $self->{_Name};
6 print "Hash entry was destroyed. Bailing out...\n"
if ! exists $self->{_Name};
}
------------------------------------------------------------------------------------
(The User Script)
#!/bin/perl

Perl Programming Copyright 2008, Learning Enterprises, Inc.


170 Module 5

7 use Employee;
8 my $empref = Employee->new(); # Create the object
9 $empref->{_Name}="Dan Savage";
$empref->{_Salary}=10000;
10 print "Name is $empref->{_Name}.\n";
11 print "Salary is $empref->{_Salary}.\n";

(Output)
10 Name is Dan Savage.
11 Salary is 10000.
4 Hash Name entry still exists.
6 Hash entry was destroyed. Bailing out...

8.7 Inheritance
• Inheritance means that a new class can inherit methods from an existing
class. The new class can then add to or modify existing code to customize
the class without having to reinvent what has been done before.
• The principle is that a class may be subdivided into a number of subclasses
that all share common features, but each subclass may provide its own addi-
tional features by refining what it borrows to a more specific functionality.
• In object oriented programming, once a class has been written and
debugged, it can be stored in a library and reused by other programmers. A
programmer can then add features and capabilities to the existing class with-
out rewriting the whole thing. This is done through inheritance, that is, by
deriving a new class from an existing class.
• The derived class can override methods in the base class.

8.7.1 The @ISA Array and Calling Methods


• The classes (packages) listed in the @ISA array are the parent or base
classes of the current class. This is how Perl implements inheritance. For
example, if a Salesman class is derived from an Employee class, the Sales-
man class must list the Employee class in the @ISA array. The relationship
is described as: the Salesman "is a" Employee. The Salesman has all the
characteristics of an Employee and then some. All employees, on the other
hand, are not necessarily salesmen.
• The @ISA array contains a list of packages where Perl will search for a
method if it can’t find it in the current package.
• If the method isn’t found in a package listed in the @ISA array, Perl
searches for an AUTOLOAD function, and calls that method instead.

Perl Programming © 2008 Learning Enterprises, Inc.


171

• If an AUTOLOAD function isn’t found, Perl searches for the last time in a
special predefined package called UNIVERSAL. The UNIVERSAL class is a
global base class for all packages, the highest class in the hierarchy of
classes.
• The @ISA array is not searched in a call to a normal subroutine, but in a
call to a subroutine if it is called with the method invocation syntax.

Example 8.7
(The Script)
#!/bin/perl
# Example of attempting inheritance without updating the @ISA array.
1 { package Grandpa;
2 $name = "Gramps";
3 sub greetme {
print "Hi $Child::name I'm your $name from package Grandpa.\n";
}
}
4 { package Parent;
# This package is empty.
}
5 {package Child;
6 $name = "Baby";
7 print "Hi I'm $name in the Child Package here.\n";
8 Parent->greetme(); # Use method invocation syntax
}
(The Output)
7 Hi I'm Baby in the Child Package here.
8 Can't locate object method "greetme" via package "Parent" at inher.file line 23.

Example 8.8
(The Script)
#!/bin/perl
# Example of attempting inheritance by updating the @ISA array.
1 { package Grandpa;
$name = "Gramps";
sub greetme {
2 print "Hi $Child::name I'm your $name from package Grandpa.\n";
}
}
3 { package Parent;
4 @ISA=qw(Grandpa); # Grandpa is a package in the @ISA array.
# This package is empty.

Perl Programming Copyright 2008, Learning Enterprises, Inc.


172 Module 5

}
5 {package Child;
$name = "Baby";
6 print "Hi I'm $name in the Child Package here.\n";
7 Parent->greetme(); # Parent::greetme() will fail. No such function in Parent
}

(The Output)
6 Hi I'm Baby in the Child Package here.
2 Hi Baby I'm your Gramps from package Grandpa.

8.7.2 Derived Classes and the @ISA Array


• Inheritance is when one class inherits methods from an existing class. The
existing class is called the base or parent class and the new class that does
the inheriting is called the derived or child class.
• The base class has capabilities that all its derived classes inherit and the
derived class can then go beyond those capabilities.
• In Perl, the derived class inherits methods from its base class (package),
and can add and modify these methods when necessary.
• The classes are inherited by putting them in the @ISA array and the meth-
ods to be exported to other modules can be specified in either the
@EXPORT or the @EXPORT_OK arrays.
• If a module functions as a class, then its methods can be called without
explicitly listing them in the @EXPORT array.
• In order to include a module or pragma into your program, the use function
is called with the module name (minus the .pm extension). The module has
the ability to export symbols to other packages that might need to use the
module.
• A special module called Exporter.pm handles the details for exporting and
importing symbols between modules. This module also needs to be included
in the @ISA array. Note in the following examples, the class method, new,
and the instance method, display, are not exported.

Perl Programming © 2008 Learning Enterprises, Inc.


173

Example 8.9
# Module Employee.pm
1 package Employee; # Base Class
use strict;
use warnings;

# Constructor method
2 sub new {
my $class = shift;
my $self = {_Name=>undef,
_Address=>undef,
_BasePay=>undef,
};
3 return bless($self, $class);
}

# Instance/access methods
4 sub set_data{
my $self=shift;
print "Enter the name of the employee. ";
chomp($self->{_Name}=<STDIN>);
print "Enter the address of $self->{_Name}. ";
chomp($self->{_Address}=<STDIN>);
print "Enter the monthly base pay for $self->{_Name}. ";
chomp($self->{_BasePay}=<STDIN>);
}

5 sub get_data{
my $self=shift;
my ($key,$value);
print "Name = $self->{_Name}.\n";
while(($key,$value)=each(%$self)){
$key =~ s/_//;
print "$key = $value.\n" unless $key eq "Name";
}
print "\n";
}
1;

Example 8.10
# Module Salesman.pm
1 package Salesman;
use strict;
use warnings;

Perl Programming Copyright 2008, Learning Enterprises, Inc.


174 Module 5

2 BEGIN{unshift(@INC, "./Baseclass");};
3 our @ISA=qw( Employee);
4 use Employee;
# What does the saleman inherit from the employee?

5 print "The salesman is an employee.\n" if Salesman->isa('Employee');


6 print "The salesman can display its properties.\n" if Salesman->can('get_data')
;

7 sub new { # Constructor for Salesman


8 my $class= shift;
9 my $emp = Employee->new; # Create a new employee
10 $emp->set_data; # Set data for the new employee
print "Before blessing package is: ", ref($emp), "\n"; # Employee
11 bless($emp, $class); # Make a salesman object
print "After blessing package is: ", ref($emp), "\n"; # Salesman
return $emp;
}

12 sub set_data{
my $self=shift;
13 my $calc_ptr = sub{ my($base, $comm, $bonus)=@_;
return $base+$comm+$bonus; };
print "Enter $self->{_Name}'s commission for this month. ";
chomp($self->{_Commission}=<STDIN>);
print "Enter $self->{_Name}'s bonuses for this month. ";
chomp($self->{_Bonuses}=<STDIN>);
print "Enter $self->{_Name}'s sales region. ";
chomp($self->{_Region}=<STDIN>);
14 $self->{_PayCheck}=&$calc_ptr( $self->{_BasePay},
$self->{_Commission},
$self->{_Bonuses}
);
}
1;

Perl Programming © 2008 Learning Enterprises, Inc.


175

Example 8.11
#!/usr/bin/perl
# User creates two saleman objects
1 use Salesman;
use strict;
use warnings;
2 my $salesguy1=Salesman->new();
3 my $salesguy2=Salesman->new();

4 $salesguy1->set_data;
5 $salesguy2->set_data;

6 $salesguy1->get_data; # Inheritance!
7 $salesguy2->get_data;

8.8 Documenting Modules


• Now that you are familiar with the object oriented syntax, we can examine
some of the modules (.pm files) from the standard Perl library. CGI.pm and
Bigfloat.pm are examples of modules that are object oriented.
• All .pm files are not object oriented. Some modules like English.pm and
Carp.pm do not use objects, but use the EXPORT arrays for exporting sym-
bols.
• Whether a module is object oriented or not, there must be some published
user interface available. The published interface is the written documenta-
tion describing how the programmer (client) should use a class (e.g. what
arguments will be passed to a method). The publicly defined interface
should not change, even if something in the class is changed.
• Perl5 introduced pod commands as a way to document modules. The pod
commands are inserted within the module ( often at the end) and are run
through a Perl filtering program which translates the commands into manual
pages.

8.9 Pod Files


• After looking in the standard Perl library, you will find that the modules,
contain documentation explaining what the module is supposed to do and
how to use it. The documentation (also called the user interface) is either
embedded within the program or placed at the end of the program right after
the special literal, __END__ .

Perl Programming Copyright 2008, Learning Enterprises, Inc.


176 Module 5

• The documentation is called pod, short for plain old documentation. A


pod file is just an ASCII text file embedded with special commands that can
be translated by one of Perl’s special interpreters, pod2html, pod2latex,
pod2text, or pod2man. The purpose is to create formatted documents that
can be represented in a number of ways. The UNIX man pages are an exam-
ple of documentation that has been formatted with nroff instructions.
• It is now easy to embed a set of formatting instructions called pod in
your scripts to provide documentation in any of the four formats, text, html,
latex, or nroff.
• The first line of the pod documentation starts with an equal sign. Each
of the words starting with an equal sign are formatting instructions for the
pod translator. Each formatting instruction must be followed by a blank
line.
• Be sure to start each line of documentation with a space in order to get
the lines to break properly.

Example 8.12
(Here is the documentation found at the end of the BigFloat.pm module in the standard Perl
library, under the subdirectory Math)

=head1 NAME

Math::BigFloat - Arbitrary length float math package

=head1 SYNOPSIS

use Math::BogFloat;
$f = Math::BigFloat->new($string);

$f->fadd(NSTR) return NSTR addition


$f->fsub(NSTR) return NSTR subtraction
$f->fmul(NSTR) return NSTR multiplication
$f->fdiv(NSTR[,SCALE]) returns NSTR division to SCALE places
$f->fneg() return NSTR negation
$f->fabs() return NSTR absolute value
$f->fcmp(NSTR) return CODE compare undef,<0,=0,>0
$f->fround(SCALE) return NSTR round to SCALE digits
$f->ffround(SCALE) return NSTR round at SCALEth place
$f->fnorm() return (NSTR) normalize
$f->fsqrt([SCALE]) return NSTR sqrt to SCALE places

=head1 DESCRIPTION

All basic math operations are overloaded if you declare your big

Perl Programming © 2008 Learning Enterprises, Inc.


177

floats as

$float = new Math::BigFloat "2.123123123123123123123123123123123";

=over 2

=item number format

canonical strings have the form /[+-]\d+E[+-]\d+/ . Input values can


have inbedded whitespace.

=item Error returns 'NaN'

An input parameter was "Not a Number" or divide by zero or sqrt of


negative number.

=item Division is computed to

C<max($div_scale,length(dividend)+length(divisor))> digits by default.


Also used for default sqrt scale.

=back

=head1 BUGS

The current version of this module is a preliminary version of the


real thing that is currently (as of perl5.002) under development.

=head1 AUTHOR

Mark Biggar

=cut

Explanation
The preceding text is what is called a "pod" file. It consists of lines starting with an
equal sign and text, followed by a blank line. Perl provides a special translator pro-
gram that reads the pod file and translates it into a readable file, either in plain text,
HTML format, nroff text, or Latex. The next section describes how to use the pod
filter programs to make the translation for you.

To get help, type: perldoc perlpod

Perl Programming Copyright 2008, Learning Enterprises, Inc.


178 Module 5

Perl Programming © 2008 Learning Enterprises, Inc.


179

8.9.1 POD Commands

See http://perldoc.perl.org/perlpod.html

• It’s easy to embed pod instructions in a text file. Commands are placed
at the beginning of a line, starting with =pod (or any other pod command)
and ending with =cut. Everything after the first =pod instruction to the
=cut instruction will be ignored by the compiler, just as comments are
ignored. The nice thing about using the commands is that they allow you to
create bold, italic, plain text, to indent, to create headings, etc. The chart
below contains a list of instructions.

• To achieve line breaks, precede each line of text that will be printed with a space.

TABLE 8.2 POD Commands


Paragraph Commands What They Do
=pod Marks the start of pod
=cut Marks the end of pod
=head1 heading Creates a level1 heading
=head2 heading Creates a level2 heading
=item * Starts a bullet list
=over N Moves over N number of spaces, usually set to 4
=back Returns indent back to default, no indent

Formatting Commands What They Do


I<text> italicizes text
B<text> emboldens text
S<text> Contains text non-breaking spaces
C<code> Contains typed text, literal source code
L<name> Creates a link (cross reference) to name
F<file> Used for listing filenames
X<index> An index entry
Z<> A zero-width character

Filter Specific Commands What They Do


=for for html specific commands, e.g. =for html
<IMG SRC=file.gif>
<B>Figure a.>/B>>
for text specific commands, e.g. =for text
text to represent what the above
image means,
for manpage specific commands

Perl Programming Copyright 2008, Learning Enterprises, Inc.


180 Module 5

8.9.2 How to Use the POD Interpreters


• The POD interpreters come with the Perl distribution and are located in
the bin directory under the main Perl directory; e.g. /usr/bin/perl5/bin.

The four interpreters are:

pod2html (translate to html)


pod2text (translate to plain text)
pod2man (translate to nroff, like man pages)
pod2latex (translate to latex)

If the interpreter is not in your search path, you can copy the one you want into
your own directory: e.g.

$ cp /usr/bin/perl5/bin/pod2text .

You may also copy the library routine into your directory; e.g.

$ cp /usr/bin/perl5/lib/BigFloat.pm .

Now when you list the contents of the directory, you should have both the
pod interpreter and the library module.

$ ls
BigFloat.pm
pod2text

Translating POD Documentation into Text.

To translate the pod commands, give the library module to the pod inter-
preter and create an output file to save the translated text. If you don’t redi-
rect the output to a file, it will simply go to the screen.

$ pod2text BigFloat.pm > BigFloat.Text

$ cat BigFloat.Text (The output file after pod commands have been
translated into text.)

Perl Programming © 2008 Learning Enterprises, Inc.


181

NAME
Math::BigFloat - Arbitrary length float math package

SYNOPSIS
use Math::BogFloat;
$f = Math::BigFloat->new($string);

$f->fadd(NSTR) return NSTR addition


$f->fsub(NSTR) return NSTR subtraction
$f->fmul(NSTR) return NSTR multiplication
$f->fdiv(NSTR[,SCALE]) returns NSTR division to SCALE places
$f->fneg() return NSTR negation
$f->fabs() return NSTR absolute value
$f->fcmp(NSTR) return CODE compare undef,<0,=0,>0
$f->fround(SCALE) return NSTR round to SCALE digits
$f->ffround(SCALE) return NSTR round at SCALEth place
$f->fnorm() return (NSTR) normalize
$f->fsqrt([SCALE]) return NSTR sqrt to SCALE places

DESCRIPTION
All basic math operations are overloaded if you declare your big
floats as

$float=newMath::BigFloat"2.123123123123123123123123123123123";

number format
canonical strings have the form /[+-]\d+E[+-]\d+/ . Input
values can have inbedded whitespace.

Error returns 'NaN'


An input parameter was "Not a Number" or divide by zero or
sqrt of negative number.

Division is computed to
`max($div_scale,length(dividend)+length(divisor))' digits by
default. Also used for default sqrt scale.

BUGS
The current version of this module is a preliminary version of

Perl Programming Copyright 2008, Learning Enterprises, Inc.


182 Module 5

the real thing that is currently (as of perl5.002) under


development.

AUTHOR
Mark Biggar

Translating POD Documentation into HTML.

To create an HTML document, copy pod2html into your directory and


type:

$ pod2html BigFloat.pm > BigFloat.html

The pod2html translator will create HTML tags for BigFloat.pm.html.


Now open your browser window and assign BigFloat.pm.html to a file pro-
tocol in the URL location box. e.g. file:/yourdirectory path/Big-
Float.pm.html.

Perl Programming © 2008 Learning Enterprises, Inc.


183

Perl Programming Copyright 2008, Learning Enterprises, Inc.


184 Module 5

8.9.3 Using A Module from the Standard Perl Library


• Having translated the pod commands in the module, BigFloat.pm, we find
that this module allows the use of floating-point numbers of arbitrary length.
Number strings have the form /[+-]\d*\.?\d*E[+-]\d+/. When NaN is
returned it means that a non-number was entered as input, that you tried to
divide by zero, or that you tried to take the square root of a negative number.
• BigFloat.pm uses the overload module which allows Perl’s built-in oper-
ators to be assigned methods that will cause the operators to behave in a new
way. The operator is the key and the method assigned is the value. (See over-
load.pm in the standard Perl library).The overload function in BigFloat.pm
allows you to change the meaning of the built-in Perl operators. If, for
example, you use the + operator, the + is a key and its value is an anonymous
subroutine that creates an object and calls the &fadd subroutine.

Example 8.13
#!/bin/perl
1 use Math::BigFloat; # BigFloat.pm is in the Math directory

2 $number = "000.95671234e-21";
3 $mathref = new Math::BigFloat("$number"); # Create the object

4 print "\$mathref is in class ", ref($mathref), "\n"; # Where is the object

5 print $mathref->fnorm(), "\n"; # Use methods from the class

6 print "The sum of $mathref + 500 is: ", $mathref->fadd("500"),"\n";


7 print "Division using overloaded operator: ", $mathref / 200.5, "\n";
8 print "Division using fdiv method:", $mathref->fdiv("200.5"), "\n";

9 print "Enter a number ";


chop($numstr = <STDIN>);

10 if ( $mathref->fadd($numstr) eq "NaN" ){ print "You didn't enter a number.\n"};

# Return value of NaN means the string is not a number or you divided by zero, or
you took the square root of a negative number.

Output
$mathref is in class Math::BigFloat
+95671234E-29
The sum of .00000000000000000000095671234 + 500 is:

Perl Programming © 2008 Learning Enterprises, Inc.


185

+50000000000000000000000095671234E-29
Division using overloaded operator:
.000000000000000000000004771632618453865336658354114713216957606
Division using fdiv method:+4771632618453865336658354114713216957606E-
63
Enter a number hello
You didn't enter a number.

Exercise 8
Part 1 Intro to Objects

1. Write a Module called Rightnow.pm that contains three methods:


a. A constructor called "new".
b. A method called "set_time" to set the time. Use the localtime function.
c. A method called "print_time" to print the time.
This method will take an argument to determine whether the time is
printed in military or standard time; e.g. print_time("Military");

d. In another Perl script, use the Rightnow module to create a Rightnow object,
and call the "print_time" method to produce output as follows:

Time now: 2:48:20 PM


Time now: 14:48:20

Perl 2 More Objects

a. In a class, create a student object. The attributes for the student object
will be sent as arguments to the constructor method. The student
object will have 3 attributes: the name of the student, the student's
Major, and a list of courses he is taking.

Create an instance method called "show_student" that will display


a student object.

The user of the module will create two student objects and display
each one.

b. Add three new attributes to the student object: the student's


address, the student's id number, the start date, and tuition; e.g.

Address: 140 Kennedy Drive, Luxembourg City, Luxembourg

Perl Programming Copyright 2008, Learning Enterprises, Inc.


186 Module 5

Id: 123A
StartDate: 01/10/04
Tuition: 5400.55

How will you manage this? If the user has so much information to
pass to the constructor, it may be a good time to create an access
method called "set_student".

Create 3 new students.

2. Create two new access methods that take arguments. One is


called "add_courses" and the other is called "drop_courses".

The user interface will allow the user to add or drop any number
of courses by sending a list of parameters to the methods;
e.g. $ptr->add_courses(["C++", "Java"]);

2. You will use a "class" method to keep track of the number of new
students. Each time you add a student, update the counter. Before
exiting the program, print the number of new students. Use the
DESTROY method.

3. From now on, send the data for each student to a file.
It should contain a line that looks like this:
John Doe:14 Main St:3456IX:Math:Trigonometry,Calculus,
French:01/01/06:4500

4. Create another file that keeps track of the number of students.


Each time you start your script, read the number from the file. When
you add a new student tell him "Welcome, John D
-------------------------------------------------------------------------
Part 3 Create an Object Oriented Module

a. Make Checking.pm object oriented. The object will be "the balance" and the
subroutines will be "methods". The constructor will contain at least two attributes:
the balance, account number. The account number will be passed to the construc-
tor as an argument. The balance will be retrieved from the register, initially set to 0.

When you create the register file, append the account number to the file name.
Include the account number, balance, and date in the register file.

Use the Checking module in the ATM user script you created earlier.

b. Can you make more that one instance of the checking object and keep track of
the balance for each account?

Perl Programming © 2008 Learning Enterprises, Inc.


187

c. Document your module with POD.

Part 4. Using @ISA and Inheritance

1. Create a Pet class with a constructor and one access method.

The constructor provides attributes for a generic pet, such as:

owner
name
sex

a. The access method is called eat(). It takes one argument:


the type of food a specific pet eats. For example, the dog eats
Alpo. The dog will not have an eat() method and will inherit from
this class.

b. Create two classes that will inherit from the Pet class; for example,
a Dog and a Cat class. They will use the Pet's constructor and
add new attributes of their own. They will have a speak() method
but not an eat() method.

Perl Programming Copyright 2008, Learning Enterprises, Inc.


188 Module 5

8.10 Using the Expect.pm Module from CPAN


• Εxpect is a program designed to control interactive applications where
there is a dialog between the program and user.
• The applications interactively prompt the user and expect the user to
respond by entering keystorkes.
• Most Expect programs are written using Tcl, but can also be written in
C or C++. Perl provides a module at CPAN, called Expect.pm to allow your
program to use Expect.

An example of a program that requires the user to interact is the passwd


program or the ftp program. These process can be automated with Expect.
Here is an example automating the passwd program that can be run from a
shell script:

spawn passwd [lindex $argv 0 ]


set password [lindex $argv 1]
expect "password:"
send "$password\r"
expect "password:"
send "$password\r"
expect eof4

User waits Interactive


for program to process
respond

User let’s Expect Interactive


Expect wait process
and respond

8.10.1 The steps for retrieving the Expect.pm Module from CPAN:

1. # perl -M'CPAN' -e 'shell;

4. From Exploring Expect by Don Libes, O’REILLY ISBN13:978-1-565-92090-3

Perl Programming © 2008 Learning Enterprises, Inc.


189

cpan> help

Display Information
command argument description
a,b,d,m WORD or /REGEXP/ about authors, bundles, distributions, modules
i WORD or /REGEXP/ about anything of above
r NONE reinstall recommendations
ls AUTHOR about files in the author's directory

Download, Test, Make, Install...


get download
make make (implies get)
test MODULES, make test (implies make)
install DISTS, BUNDLES make install (implies test)
clean make clean
look open subshell in these dists' directories
readme display these dists' README files

2. install Expect (The install process should start)

3. You may get an error from cpan such as:


"Writing Makefile for Expect
---- Unsatisfied dependencies detected during [R/RG/RGIERSIG/Expect-
1.21.tar.gz] --
IO::Pty
IO::Tty
Shall I follow them and prepend them to the queue
of modules we are processing right now? [yes] follow
-- NOT OK
Running make test
Can't test without successful make
Running make install
make had returned bad status, install seems impossible

Go to the build directory and manually run make and install:

# cd /usr/y/build

# ls
DBI-1.55 Expect-1.21 IO-Tty-1.07

# cd IO*

# ls

Perl Programming Copyright 2008, Learning Enterprises, Inc.


190 Module 5

ChangeLog Makefile README Tty.xs try


MANIFEST Makefile.PL Tty conf xssubs.c
META.yml Pty.pm Tty.pm test.pl

# perl Makefile.PL

After this finishes:

# make

And then:

# make install

Now you should be ready to go!!!!

8.10.2 Using Expect.pm

Documentation:
perldoc Expect

NAME
Expect.pm - Expect for Perl

VERSION
1.21

SYNOPSIS
use Expect;

# create an Expect object by spawning another process


my $exp = Expect->spawn($command, @params)
or die "Cannot spawn $command: $!\n";

# or by using an already opened filehandle (e.g. from Net::Telnet)


my $exp = Expect->exp_init(\*FILEHANDLE);

# if you prefer the OO mindset:


my $exp = new Expect;
$exp->raw_pty(1);
$exp->spawn($command, @parameters)
or die "Cannot spawn $command: $!\n";

# send some string there:

Perl Programming © 2008 Learning Enterprises, Inc.


191

$exp->send("string\n");

# or, for the filehandle mindset:


print $exp "string\n";

# then do some pattern matching with either the simple interface


$patidx = $exp->expect($timeout, @match_patterns);
<continues here>

USAGE
new Expect ()
Creates a new Expect object, i.e. a pty. You can change parameters
on it before actually spawning a command. This is important if you
want to modify the terminal settings for the slave. See slave()
below. The object returned is actually a reblessed IO::Pty file-
handle, so see there for additional methods.

Expect->exp_init(\*FILEHANDLE) or
Expect->init(\*FILEHANDLE)
Initializes $new_handle_object for use with other Expect functions.
It must be passed a _reference_ to FILEHANDLE if you want it to
work properly. IO::File objects are preferable. Returns a refer-
ence to the newly created object.

You can use only real filehandles, certain tied filehandles (e.g.
Net::SSH2) that lack a fileno() will not work. Net::Telnet objects
can be used but have been reported to work only for certain hosts.
YMMV.

Expect->spawn($command, @parameters) or
$object->spawn($command, @parameters) or
new Expect ($command, @parameters)
Forks and execs $command. Returns an Expect object upon success or
"undef" if the fork was unsuccessful or the command could not be
found. spawn() passes its parameters unchanged to Perls exec(), so
look there for detailed semantics.

Note that if spawn cannot exec() the given command, the Expect
object is still valid and the next expect() will see "Cannot exec",
so you can use that for error handling.

Also note that you cannot reuse an object with an already spawned
command, even if that command has exited. Sorry, but you have to
allocate a new object...

Perl Programming Copyright 2008, Learning Enterprises, Inc.


192 Module 5

Example 8.14
1 #!/usr/bin/perl -w -s
2 # $Id: get_file,v 1.1 2001/04/08 20:39:12 jsh Exp $
3 use File::Basename;
4 our $debug;
5 use Expect;

6 @ARGV == 1 or die "usage: $0 ftp-site file\n";


7 my ($host, $path) = split ':', shift;
8 die "usage: $0 host:path" unless defined $path;
9 my ($file, $dirname) = fileparse $path;

10 my $t = 30;
11 my $ftp_prompt = 'ftp> ';

12 if ($debug) {
13 $Expect::Debug=1;
14 $Expect::Exp_Internal=1;
15 }

16 my $ftp = Expect->spawn("ftp", $host);


17 $ftp->expect($t, "Name") or
18 die "Never got username prompt on $host, " .
19 $ftp->exp_error() . "\n";

20 print $ftp "anonymous\r";


21 $ftp->expect($t, '-re', 'Password:\s*') or
22 die "Never got password prompt on $host, " .
23 $ftp->exp_error() . "\n";

24 print $ftp $ENV{USER} . '@' . `dnsdomainname` . "\r";


25 $ftp->expect($t, '-re', $ftp_prompt) or
26 die "Never got ftp prompt after sending username and password, " .
27 $ftp->exp_error() . "\n";

28 print $ftp "cd $dirname\r";


29 $ftp->expect($t, '-re', $ftp_prompt) or
30 die "Never got ftp prompt after attempting to change directories, " .
31 $ftp->exp_error() . "\n";
32
33 print $ftp "get $file\r";
34 $ftp->expect($t, '-re', $ftp_prompt) or
35 die "Never got ftp prompt after attempting to get $file, " .
36 $ftp->exp_error() . "\n";

Perl Programming © 2008 Learning Enterprises, Inc.


193

37 print $ftp "quit\r";


38 $ftp->expect($t, '-re', "Goodbye.") or
39 die "Never got 'Goodbye.', " .
40 $ftp->exp_error() . "\n";

41 $ftp->hard_close();

$ perl session.plx alice.uni-passau.de:/pub/welcome.msg


alice.uni-passau.de
Connected to alice.fim.uni-passau.de.
220 Welcome to ftp.algebra.fim.uni-passau.de
Name (alice.uni-passau.de:ellie): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd /pub/
cd /pub/
250 Directory successfully changed.
ftp> get welcome.msg
local: welcome.msg remote: welcome.msg
229 Entering Extended Passive Mode (|||12586|)
200 EPRT command successful. Consider using EPSV.
550 Failed to open file.
ftp> quit
221 Goodbye.

Perl Programming Copyright 2008, Learning Enterprises, Inc.


194 Module 5

8.11 Using a Juniper Library

Physical Setup

Ingress interfaces Egress Interfaces

Router Tester DUT(Device Under Test)


1 1
Tx Juniper Rx Forwarding Planee
TGN Router TGN Testing Setup

N M

Routing Domain (1) Routing Domain (2)

TGN -- Traffic Generator

Ingress Interface -- Traffic Enters the DUT through these

Egress Interface -- Traffic Exits teh DUT through these

Note that interfaces carry traffic in either direction.


Tx and Rx TGN are the same system but different sets of interfaces.

N and M are chosen in the params files (*.params)

3 Files are involved: Forwarding.pm -- Perl module -- configures the interfaces


gets input from params files.
forwarding-- executable starter file,sets up the
Perl environment, paths, libraries, etc.
forward.params -- Defines the topology and interfaces for both
ingress, egress and DUC, describes whole setup,
all hard coding done here.

Perl Programming © 2008 Learning Enterprises, Inc.


195

8.11.1 The Files


The listings below come from four files:
• forwarding
• Forwarding.pm
• mohwak.params
• forwarding.91486.log

Files Order of Processing Description

(.pl file -- starting point)


forwarding ./forwarding
usage: ./forwarding [ -p <file.params> ]

Not: if "-p" option is not provided, the


default params file will be:
forwarding.params

Source all the JT lib


files and prepare the
JT environment

forwarding.params ( .params file that contains topology info


( or any file ending Call params File and system and user variables)
with .params )

Generate user.params
and check topology;
initiate log file.

Define user procedures


Forwarding.pm (modular functions)

log files

Perl Programming Copyright 2008, Learning Enterprises, Inc.


196 Module 5

8.11.2 The forwarding File

To start up: ./forwarding -p mohwak.params

Example 8.15
#!/volume/perl/bin/perl
# Template: S03.02.P09.T05
# Copyright (C) 2003-2004, Juniper Networks, Inc.
# All rights reserved.
#
# Author: Phil Wisdom
# %SYN%: Tests forwarding on OC192 or something.
# %URL%: None yet, sucka!
# %REV%: Script revision is tracked by $VERSION found below.
# %DESCR%: For fun configuring of traffic meshes on OC192 links for RLI
2741 and others.
#
#-----------------------------------------------------------------------
use warnings;
use strict;
use vars qw($VERSION);

use lib qw(/volume/labtools/lib /volume/labtools/lib/scaling .);

use JT::Test;
use Forwarding; # See Forwarding.pm

$VERSION = do { my @r = (q$Revision: 1.8 $ =~ /\d+/g); sprintf "%d."."%02d" x


$#r, @r };

main: {
my $t = JT::Test->init;
$t->setup;
$t->run_testcases;
$t->close;
}

8.11.3 The Forwarding.pm Module

This is a large file. The following example represents sections, but not all
of the file.

Perl Programming © 2008 Learning Enterprises, Inc.


197

Example 8.16
# template: S03.02.P09.T05
# Copyright (C) 2003-2004, Juniper Networks, Inc.
# All rights reserved.
#
# This Perl module is used by 'Forwarding testcases'.
#
# Author: Vinay Kulkarni
# Acknowledgement: Phil Wisdom
# Description: The purpose of this .pm is a library to quickly configure
# and reconfigure traffic meshes for OC192 links.

1 package Forwarding;
2 use warnings;
3 use strict;
4 use Exporter; # Exporting symbols to user’s symbol table
5 use JT;
use JT::Test;
use JT::Scaling;
use RT_Scaling;
use SP_Config;

6 use vars qw(@ISA @EXPORT $VERSION); # Allow global variables

$VERSION = do { my @r = (q$Revision: 1.5 $ =~ /\d+/g); sprintf "%d."."%02d"


x $#r, @r };

7 @ISA = qw(Exporter); # Module that exports symbols


8 @EXPORT = qw( # List of function name to be exported this module
configure_traffic
setup
test
test_fail
);

9 sub setup {
10 my $t = shift; # Test object
11 my $sub = JT::sub_name;
12 my ($p, @r, $v, $rt);
13 $t->get_handles(params=>\$p, rtrs=>\@r, vars=>\$v, rt=>\$rt);
## call object method
$t->checkpoint(msg=>"Configuring RT and R0");
my $status = $t->ok;

Perl Programming Copyright 2008, Learning Enterprises, Inc.


198 Module 5

#######################
# setup trend_data file
#######################
### Call a function to create the trend_data file and assign its name as a
### value to an anonymous hash referenced by pointer $v:
### the key to the hash:dfh (data file handle)
14 $v->{dfh} = JT::create_file( ext => "trend_data", headline => 1 );
## $v is a pointer to a hash. Function create_file reutrns value (file name)
## assigned to hash where key is ’dfh’
15 my $date = `date "+DATE: %Y-%m-%d %H:%M:%S"`; # Unix/Linux
chomp $date;
my $junos = $r[0]->get_version();
### Print to the file referenced by $v the current date and version info
print {$v->{dfh} } "$date $0 $junos DUT $v->{R0_NAME}
$v->{R0_MODEL}\n";

16 if ($v->{ENABLE_BGP}) { ### if this property has been set


17 my $num_routes = $v->{TOTAL_BGP_PEERS}*$v->{MAX_ROUTES};
print {$v->{dfh}} "bgp:enabled number_of_peers:
$v->{TOTAL_BGP_PEERS} number_of_routes:$num_routes\n";
} else {
17 print {$v->{dfh}} "bgp:disabled\n";
}
### Add data to a file that was created in line 14.
18 print {$v->{dfh}} "throughput:$v->{TRAFFIC_LOAD}\n";
print {$v->{dfh}} "duration:$v->{TRAFFIC_DURATION}\n";

##############################################################
### Forwarding.pm continues from the last example. We are still in the
### setup() routine

###############
# configure DUT (Juniper Router)
###############

1 my $r0_interfaces = $p->access("r0.interfaces");
2 foreach (keys %$r0_interfaces) {
3 my $pic = $p->access("r0.interfaces.$_.pic");
4 if ($pic =~ /so/) {
### Call the config_build function. Pass a hash to set the interface to
### configure the juniper router
5 $r[0]->config_build(cmd=>["set interface $pic encapsulation ppp"]);
6 $r[0]->config_build(cmd=>["set interface $pic sonet-options fcs 32"]);
}

Perl Programming © 2008 Learning Enterprises, Inc.


199

### If BGP is enabled set up the ip address and protocols


7 if ($v->{ENABLE_BGP}) {
8 my $x_ip = $p->access("r0.interfaces.$_.x-ip");
9 my ($rtr1,$tester1) = get_first_and_last(net=>$x_ip);
10 $r[0]->config_build("set protocols bgp group internal type
$v->{BGP_TYPE}");
$r[0]->config_build("set protocols bgp group internal neighbor $tester1");
$r[0]->config_build("set protocols bgp hold-time
$v->{BGP_HOLD_TIME}");
}
}

11 if ($v->{ENABLE_BGP}) {
$r[0]->config_build("set routing-options autonomous-system
$v->{AS}");
}

12 $r[0]->commit;
##################################################

###############
# configure RT0 Still in the setup() routine.
###############
13 my $i = 0;
14 my $rt_interfaces = $p->access("rt0.interfaces");
15 my @port_to_ip;

=pod

foreach (keys %$rt_interfaces) {


my $rt_port = $p->access("rt0.interfaces.$_.pic");
my $rt_ip = $p->access("rt0.interfaces.$_.x-ip");
my $rt_type_array = $p->access("rt0.interfaces.$_.type");
my $rt_speed = ${$rt_type_array}[1];
my $rt_type = ${$rt_type_array}[0];
put_log(" Port type: @$rt_type_array - $rt_type \n");
$port_to_ip[$i] = {port=>$rt_port, ip=>$rt_ip, type=>$rt_type,
speed=>$rt_speed};
$i++;
}
=cut

16 foreach (keys %$rt_interfaces) {


my $type="";

Perl Programming Copyright 2008, Learning Enterprises, Inc.


200 Module 5

my $speed="";
my $rt_port = $p->access("rt0.interfaces.$_.pic");
my $rt_ip = $p->access("rt0.interfaces.$_.x-ip");
17 if ( $v->{SET_CARD_TYPE} ) {
$type = $v->{CARD_TYPE};
$speed = "10G";
}
### An array of ports attributes being set
18 $port_to_ip[$i] = {port=>$rt_port, ip=>$rt_ip, type=>$type,
speed=>$speed};
$i++;
}

19 $rt->close () unless ($rt->init_modules (port => \@port_to_ip, reboot=>0));

20 if ($v->{ENABLE_BGP}) {
21 my $i = 1;
foreach (keys %$rt_interfaces) {
my $rt_port = $p->access("rt0.interfaces.$_.pic");
my $port_handle = $rt->{PORT_TO_HANDLE_MAP}->{$rt_port};
my $x_ip = $p->access("rt0.interfaces.$_.x-ip");
my ($rtr1,$tester1) = get_first_and_last(net=>$x_ip);
22 $rt->close () unless ($rt->add_rt_bgp_to_links(
port_handle=>$port_handle,
num_peers=>1,
num_routes=>$v->{MAX_ROUTES},
type=>"internal",
route_ip=>"$i.0.0.0",
sut_ip=>$rtr1,
tester_ip=>$tester1,
tester_as=>$v->{AS})
);
$i++;
} # End foreach loop
} # End if

23 configure_traffic($t);
24 configure_traffic_statistics($t);

# need to make this useful, put in failure cases for RT setup


25 if ( 1 ) { # How can this be false? Must have made it this far!
$status &= $t->ok("Setup is complete."); # Bitwise &
} else {
$status &= $t->nok("Something got screwy in setup.");
}

Perl Programming © 2008 Learning Enterprises, Inc.


201

26 return $status;
} # End the setup() routine

1 sub test {
2 my $t = shift; # Test object
my $sub = JT::sub_name;
3 my ($p, @r, $v, $rt); $t->get_handles(params=>\$p, rtrs=>\@r,
vars=>\$v, rt=>\$rt);
my $testname = "REFERENCE"; # can be "REFERENCE", "FIREWALL"

my $status = $t->ok;
4 my $rt_interfaces = $p->access("rt0.interfaces");
my $jcells;

########
5 my $r0_interfaces = $p->access("r0.interfaces");
my $fpc;
6 foreach (keys %$r0_interfaces) {
my $pic = $p->access("r0.interfaces.$_.pic");
$jcells = (($pic =~ /so/) ? 71 : 25);
$fpc = $r[0]->get_pfe(if=>$pic);
}
########

7 if ($v->{ENABLE_BGP}) {
$rt->start_routing;
$status &= $r[0]->chk_bgp_peer(num=>$v->{TOTAL_BGP_PEERS},
timeout=>$v->{BGP_PEER_TIMEOUT});
my $bgp_target = $v->{TOTAL_BGP_PEERS} * $v->{MAX_ROUTES};
$status &= monitor_route_summary(rtr=>$r[0], protocol=>'BGP',
target=>$bgp_target, timeout=>$v->{BGP_ROUTES_TIMEOUT});
}

# for all my packet sizes, execute traffic and trend results -


# after each test, modify the traffic meshes with the new packet size

# my @packetsizes = @{$v->{PACKETSIZES}};
# my $packetsize;

8 my @packetsizes;
9 my $packetsize;

10 if ($v->{PACKET_SWEEP}) {
11 for(my $i=40; $i<108; $i++) {

Perl Programming Copyright 2008, Learning Enterprises, Inc.


202 Module 5

# for(my $i=40; $i<256; $i++) {


push @packetsizes, $i;
}
=pod
12 for(my $i=9; $i<$jcells; $i++) {
13 push @packetsizes, $i*64, $i*64+1;
}
=cut
put_log (" *********Packet Sizes: @packetsizes ******************\n");
} else {
$t->log ("Packet Sweep not set ... ");
13 @packetsizes = @{$v->{PACKETSIZES}};
put_log (" *********Packet Sizes: @packetsizes ******************\n");
} # End if

14 put_log(" Configure the filter now ... ");


# JT::pause(1);

15 $t->sleep(10);

################################################################
##############################
# Get the snapshot before test, but after all the configs are committed.
# This will give us an idea about the occupied resources!

################################################################
##############################

$t->log(msg=>"R0 PRE TEST MEASUREMENTS FOR $testname CONFIG");


$r[0]->cli(cmd=>"show chassis routing-engine"); # what RE?
$r[0]->cli(cmd=>"show task memory detail"); # rpd details
$r[0]->cli(cmd=>"show system virtual-memory"); # kernel
$r[0]->shell(cmd=>"top -nd1"); # RE mem usage
$r[0]->cli(cmd=>"show pfe route summary"); # routes in the pfe
$r[0]->vty(name=>"$fpc", cmd=>"show memory"); # power pc memory,
ukern memory
$r[0]->vty(name=>"$fpc", cmd=>"show jtree 0 memory"); # sram memory
$r[0]->vty(name=>"$fpc", cmd=>"show filter memory"); # sram used by
policers/filters

################################################################
##############################
# Continue with the actual test with traffic flow

Perl Programming © 2008 Learning Enterprises, Inc.


203

################################################################
##############################

for (my $iter = 0; $iter <= $v->{FIREWALL}; $iter++) {


if ($iter == 1) {
# Configure the firewall filter
$testname = "FIREWALL";

my $load_time = time;
$r[0]->load_config_file(
local_file=>$v->{FW_CONF_FILE},
option=>'merge',
timeout=>3600,
keep=>'yes',
synchronize=>'false',
);
$load_time = (time - $load_time);
$t->log(msg=>"X-FILTER-LOAD-TIME $load_time");

my @commit_time = $r[0]->commit(timeout=>3600,synchronize=>'false');
$t->log("X-FILTER-COMMIT-TIME for DUT is $commit_time[1]");

#################################
# Install it on the interfaces
#################################
my $k = 0;
my $r0_interfaces = $p->access("r0.interfaces");
foreach (keys %$r0_interfaces) {
my $pic = $p->access("r0.interfaces.$_.pic");
if ($v->{FULL_MESH}) {
} else {
if ($k < $v->{NUM_SRC_PORTS}) {
$k++;
} else {
$r[0]->config_build(cmd=>["set interface $pic unit 0 family inet filter
output test_filter"]);
$k++;
}
}
}

my @commit_time = $r[0]->commit(timeout=>3600,synchronize=>'false');
$t->log("X-FILTER-COMMIT-TIME for DUT is $commit_time[1]");

Perl Programming Copyright 2008, Learning Enterprises, Inc.


204 Module 5

$t->sleep(30);

################################################################
# Make sure the filter has been installed

################################################################
#

my $start_time = time;
my $wait_count = 1;

while (1) {
$r[0]->cli(cmd=>"show firewall | match test_filter | count", timeout=>600);
my $filter_count = $r[0]->get_response();
$filter_count =~ s/\D+//g;
$t->log(msg=>"filter count is $filter_count");
last if ($filter_count == 1);
return $t->nok("pfe never got all the filters?") if ($wait_count > 100);
$t->sleep(10);
$wait_count++;
}

###############################
# break down traffic by DS bits
###############################
$rt->invoke("AgtStatisticsList ListHandles");
my $response = $rt->get_response;
my $junk;
($junk, $response) = split /{/, $response;
($response, $junk) = split /}/, $response;
my @stat_handles = split / /, $response;
foreach (@stat_handles) {

$rt->invoke("AgtStatisticsList GetName $_");


my $stat_name = $rt->get_response;
$t->log("stat_name is $stat_name");
if (($stat_name =~ /0x/) && !($stat_name =~ /stats/)) {

$rt->invoke("AgtStreamStatistics GetAccumulatedValues $_");


my $stats = $rt->get_response;
print " GETACCUMULATEDVALUES : $stats \n";
($junk, $stats) = split /{/, $stats;
($stats, $junk) = split /}/, $stats;
my @stat_numbers = split / /, $stats;

Perl Programming © 2008 Learning Enterprises, Inc.


205

my $number;
my $total=0;
my $i=0;
foreach $number (@stat_numbers) {
$t->log("STAT ELEMENTS: $stat_numbers[$i] $number\n");
$total += $number;
$i++;
foreach $number (@stat_numbers) { $total += $number; }
my $DS_bit_percent;
if ($throughput->[5] > 0) {
$DS_bit_percent = ($total / $throughput->[5]) * 100;

}
if ($stat_name =~ /stats/) {
$rt->invoke("AgtStreamStatistics GetAccumulatedValues $_");
my $stats = $rt->get_response;
($junk, $stats) = split /{/, $stats;
($stats, $junk) = split /}/, $stats;
my @stat_numbers = split / /, $stats;
my ($stream_min, $stream_max, $stream_avg);
my $i = 0; my $number;
($junk, $stats) = split /{/, $stats;
($stats, $junk) = split /}/, $stats;
my $num_streams = @stat_numbers;
$num_streams = $num_streams / 3; #min, max, latency
foreach $number (@stat_numbers) {
if ($i == 0) { $stream_min += $number; }
if ($i == 1) { $stream_max += $number; }
if ($i == 2) { $stream_avg += $number; }
$i++;
if ($i > 2) { $i = 0; }
}
$stream_min = ($stream_min / $num_streams) / 100;
$stream_max = ($stream_max / $num_streams) / 100;
$stream_avg = ($stream_avg / $num_streams) / 100;

$t->log("$stat_name min latency : $stream_min us");


$t->log("$stat_name max latency : $stream_max us");
$t->log("$stat_name avg latency : $stream_avg us");
print {$v->{dfh}} "latency (min/max/avg) for $stat_name: $stream_min
$stream_max $stream_avg\n";
}

Perl Programming Copyright 2008, Learning Enterprises, Inc.


206 Module 5

}
}

############
# trend data
############

$v->{dfh} = JT::create_file( ext => "trend_data", headline => 0 );


print {$v->{dfh}} "size_count:$i pktsize:$packetsize percent:$traffic_percent
tx:$throughput->[4] rx:$throughput->[5] min_l:$latency->[0] max_l:$latency->[1]
avg_l:$latency->[2] pps:$agg_pps\n";

################################################################
##############################
# Get the snapshot after test. This will give us the stats on how the resourc-
es were taxed

################################################################
##############################

$t->log(msg=>"R0 POST TEST MEASUREMENTS FOR $testname CON-


FIG");
$r[0]->cli(cmd=>"show chassis routing-engine"); # what RE?
=pod
$r[0]->cli(cmd=>"show task memory detail"); # rpd details
$r[0]->cli(cmd=>"show system virtual-memory"); # kernel
$r[0]->shell(cmd=>"top -nd1"); # RE mem usage
$r[0]->cli(cmd=>"show pfe route summary"); # routes in the pfe
$r[0]->vty(name=>"$fpc", cmd=>"show memory"); # power pc
memory, ukern memory
$r[0]->vty(name=>"$fpc", cmd=>"show jtree 0 memory"); # sram memory
$r[0]->vty(name=>"$fpc", cmd=>"show jtree 1 memory"); # sram memory
$r[0]->vty(name=>"$fpc", cmd=>"show filter memory"); # sram used by
policers/filters
=cut

########################################
# Move to the next packet size
########################################
$i++;

}
} # End of for loop with $iter

Perl Programming © 2008 Learning Enterprises, Inc.


207

# JT::pause(1);

print {$v->{dfh}} "---------------------------------\n";


return $status;
}

sub test_fail {
my $t = shift; # Test object
my $sub = JT::sub_name;
my ($p, @r, $v, $rt); $t->get_handles(params=>\$p, rtrs=>\@r, vars=>\$v,
rt=>\$rt);

$t->checkpoint(msg=>"Test failed...");

my $status = $t->nok;

return $status;
}

sub configure_traffic {
my $t = shift; # Test object
my $sub = JT::sub_name;
my ($p, @r, $v, $rt); $t->get_handles(params=>\$p, rtrs=>\@r, vars=>\$v,
rt=>\$rt);

$t->checkpoint(msg=>"Configuring traffic based on .params file");


my $status = $t->ok;
my (@rt_ports, @t_map);

my $rt_interfaces = $p->access("rt0.interfaces");
my $i = 0;
my $bw;

my @stream_vals = @{$v->{DS_STREAM_VALS}};
my @stream_bws = @{$v->{DS_STREAM_BWS}};
my @streams;
$i = 0;

# let's define our source ports and destination ports


my $src_port_counter = 0;
my $dst_port_counter = 0;
my $traffic_sources = "[ list ";
my $traffic_destinations = "[ list ";

Perl Programming Copyright 2008, Learning Enterprises, Inc.


208 Module 5

my $traffic_mesh_ports = " [ list ";


my (@port_array, @src_array, @dst_array, @port_handles);

# JT::pause(1);

} else {
my $i=0;
my @hPort;
my @hProfile;
my @hStream;
foreach (keys %$rt_interfaces) {

################################################################
#######
# Configure one Profile per port (if the traffic profile is uniform)

################################################################
#######

# $t->log( "configuring Profile on port $_");


# $rt->invoke("AgtPortSelector AddPorts $_");
# $hPort[$i] = $rt->get_response;

# $hPort[$i] = $p->access("rt0.interfaces.$_.pic");
$hPort[$i] = $rt->{PORT_TO_HANDLE_MAP}->{$p->access("rt0.interfac-
es.$_.pic")};
$rt->invoke("AgtProfileList AddProfile $hPort[$i]
AGT_CONSTANT_PROFILE");
$hProfile[$i] = $rt->get_response;
put_log("Profile: $hProfile[$i] on port handle $hPort[$i]");
my $profilename = "AGT_CONSTANT_PROFILE" . $hProfile[$i];
$rt->invoke("AgtProfileList SetName $hProfile[$i] $profilename");
$rt->invoke("AgtConstantProfile SetMode $hProfile[$i]
AGT_TRAFFIC_PROFILE_MODE_CONTINUOUS");
$rt->invoke("AgtConstantProfile SetAverageLoad $hProfile[$i] $v-
>{TRAFFIC_LOAD} $v->{TRAFFIC_UNIT}");
$rt->invoke("AgtConstantProfile Enable $hProfile[$i]");

################################################################
####
# Add traffic stream(s) to each of the profiles created above

################################################################
####

Perl Programming © 2008 Learning Enterprises, Inc.


209

##########################################

=pod
put_log(msg=>" Defining profiles...");
$rt->invoke("AgtProfileList AddProfile $traffic_mesh_ports[0]
AGT_CONSTANT_PROFILE");
my $response = $rt->get_response();
my $hProfile = parse_resp($response);

$rt->invoke("AgtProfileList SetName $hProfile \"Dummy \"");


$rt->invoke("AgtConstantProfile SetMode $hProfile
AGT_TRAFFIC_MODE_CONTINUOUS");
$rt->invoke("AgtConstantProfile Enable $hProfile");
$t->log(" Setting up Full Mesh traffic: \n");
$rt->invoke("AgtMeshList AddMeshWithNewProfiles AGT_IPV4_MESH");
my $mesh_handle = $rt->get_response;
$rt->invoke("AgtIpv4Mesh SetTrafficDistribution $mesh_handle
AGT_TRAFFIC_FULLY_MESHED");
$rt->invoke("AgtIpv4Mesh AddSources $mesh_handle $traffic_mesh_ports");
=cut

=pod
$rt->invoke("AgtMeshList ListHandlesByType AGT_IPV4_MESH");
my $meshes = $rt->get_response();
my $bracket;
($bracket, $meshes) = split /{/, $meshes;
($meshes, $bracket) = split /}/, $meshes;
my @mesh_handles = split / /, $meshes;

foreach (@mesh_handles) {
# $rt->invoke("AgtIpv4Mesh GetPdu $_");
$rt->invoke("AgtStreamGroup GetPdu $_");
my $pdu = $rt->get_response;
# $rt->invoke("AgtIpPdu SetPacketLength $pdu $packetsize");
$rt->invoke("AgtStreamGroup SetLengthMode $pdu
AGT_PACKET_LENGTH_MODE_IP_PACKETS");
$rt->invoke("AgtStreamGroup SetLength $pdu
AGT_PACKET_LENGTH_FIXED $packetsize");
# $rt->invoke("AgtIpPdu SetIpFieldValue $pdu AGT_IP_TOS_PRECEDENCE
0x6"); # Set the ToS field
}
=cut

# JT::pause(1);

Perl Programming Copyright 2008, Learning Enterprises, Inc.


210 Module 5

return $status;
}

1; # MUST RETURN 1 AT THE END OF MODULE.

8.11.4 A params file


---------------------------------------------------------------
# mohwak.params
# Template: S03.02.P09.T05
# Copyright (C) 2003-2004, Juniper Networks, Inc.
# All rights reserved.
#
x-params-file-version "$Id$";

x-no-resource-reservation-check 1;

#########################
# JT defaults :
#########################

x-show-log 1;
x-log-listing-on-close 2;
x-no-check-interface-status 1;
x-no-check-interface-ping 1;
x-no-commit-on-cleanup 1;
x-no-config-save-on-setup 1;
x-no-save-base-test-config 1;
x-no-params-expand 0;

x-no-params-expand 0;
#x-params-import "";
x-show-log 1;
x-log-level "trace"; # info | trace
# x-log-dir "";
x-xlog 0; # wow
x-cmd-log-level "trace";
x-resp-log-level "trace";
x-no-log-header 0;
x-show-expect-log 0;
x-set-expect-errors 10;
x-log-listing-on-close 0;

Perl Programming © 2008 Learning Enterprises, Inc.


211

x-no-checkpoint 0;
x-no-os-version-chk 0;
x-no-os-version-chk-on-init 0;
x-no-config-save-on-setup 1;
x-no-save-base-test-config 1;
x-no-base-config-cleanup 1;
x-no-setup-interfaces 0;
x-no-commit-on-cleanup 1;
x-no-commit-on-config-setup 0;
x-sleep-interval-after-test-config 10;
x-no-check-interface-status 1;
x-no-check-interface-ping 1;
x-setup-only 0;
x-test-only 0;
x-no-postmortem 0;
x-postmortem-always 0;
x-no-restore-config 0;
x-parallel-timeout 900;
x-timeout-commit-cleanup 3600;
x-timeout-commit-test-config 3600;
x-timeout-restore-config 100;
x-timeout-restore-base-test-config 3600;

x-set-user-configs"&Forwarding::setup";
x-task-memory-snapshot 0;

x-test-descr " Performance with DCP enabled for default routing table
";

x-test-topology "

RT0_NAME
RT0------R0-------RT0
R0_NAME RT0_NAME
";

# Change this filename as per the required conf.


x-my-firewall "0"; # Set this to 1 if firewall is to be configured
x-my-fw-conf-file "/homes/vinay/Configs/IP_250000_FiltersOnly.conf";

##########################
# TRAFFIC KNOBS
##########################

x-my-traffic-load "9450"; # Change this according to the units

Perl Programming Copyright 2008, Learning Enterprises, Inc.


212 Module 5

x-my-traffic-unit "AGT_UNITS_MBITS_PER_SEC" ; #
"AGT_UNITS_PERCENTAGE_LINK_BANDWIDTH"; #
AGT_UNITS_MBITS_PER_SEC | AGT_UNITS_PACKETS_PER_SEC

x-my-packet-sweep "1"; # set this to zero if you need customized packetsizes array
as shown below
# if set to 1, the loop inside the program will decide the range of
packetsizes
# 40 through 9000+ bytes
#x-my-packetsizes ("40" "53" "64" "75" "90" "110" "128" "256" "512" "1024");
x-my-packetsizes ("52" "53" "54" );
#x-my-packetsizes ("40" "53" "64" "65" "75" "90" "100" "110" "114" "128" "129"
"140" "150" "160" "178" "192" "193" "200" "210" "225" "242" "256" "257" "265" "275"
"290" "300" "316" "320" "321" "340" "350" "360" "370" "384" "385" "390" "400" "410"
"425" "434" "448" "449" "460" "475" "490" "498" "512" "513" "1024" "2048");
x-my-traffic-duration "60"; # seconds
x-my-color "color-blind"; # "color-aware"

x-my-full-mesh "0"; # all ports send to all other ports


x-my-num-src-ports "2"; # full-mesh overrides, if no full-mesh then this sets up
x-my-num-dst-ports "2"; # the number of source ports and destination ports
# src + dst must equal total # of ports!

x-my-set-card-type "0"; # set this to zero if you want the default card type
x-my-card-type "10GBASE_R"; # 10GBASE_W | 10GBASE_W_PACKET |
10GBASE_R_PACKET
x-my-card-speed "10G"; # 1000 | OC192 | OC12

x-my-ds-streams "0"; # on/off switch


x-my-ds-stream-bws ("4200" "4200" );
x-my-ds-stream-vals ("0xCC" "0xC8" );

# Change this filename as per the required conf.


#x-my-fw-conf-file "/homes/vinay/Configs/IP_EFTF_1000.conf";
#x-my-fw-conf-file "/homes/vinay/Configs/IP_EFTF_125000.conf";

##########################
# PROTOCOL KNOBS2
##########################

x-my-as "100";
x-my-enable-bgp "1";
x-my-total-bgp-peers "2";
x-my-bgp-peer-timeout "300";
x-my-bgp-routes-timeout "600";

Perl Programming © 2008 Learning Enterprises, Inc.


213

x-my-bgp-type "internal";
x-my-max-routes "1000";
x-my-bgp-hold-time "600";

##########################
# TESTCASES
##########################
x-testcase-001 (
"x-is-run"1
"x-cmd""&Forwarding::test"
"x-cmd-on-fail""&Forwarding::test_fail"
"x-reset-config"0
);

##########################
# TOPOLOGY
##########################

r0 {
x-dut 1;
system {
name "mohawk";
x-my-as 100;
}
interfaces {
r0rt0-0 {
type "sonet";
x-ip "192.1.1.1/30";
name "so-7/0/0.0";
}
r0rt0-1 {
type "sonet";
x-ip "192.2.1.1/30";
name "so-7/1/0.0";
}
# r0rt0-2 {
# type "sonet";
# x-ip "192.3.1.1/30";
# name "xe-0/2/0.0";
# }
# r0rt0-3 {
# type "sonet";
# x-ip "192.4.1.1/30";
## name "xe-0/3/0.0";
# }

Perl Programming Copyright 2008, Learning Enterprises, Inc.


214 Module 5

}
}
rt0 {
system {
name "art4-ipv6";
make "Agilent";
model "RT";
}
interfaces {
r0rt0-0 { type "sonet"; x-ip "192.1.1.1/30"; }
r0rt0-1 { type "sonet"; x-ip "192.2.1.1/30"; }
# r0rt0-2 { type "sonet"; x-ip "192.3.1.1/30"; }
# r0rt0-3 { type "sonet"; x-ip "192.4.1.1/30"; }
}
}

8.11.5 Log files (sample)

===== Display starts at offset 16526751 within file of length 16657823. ====
===== Use File->Reload (Cmd-R) to display more. ====
23 [TRACE] [RT0 tx-art1.1]
Apr 12 11:13:23 [RT:TRACE] [tx-art1] 0 "AGT_STATISTICS_IP405"
Apr 12 11:13:23 [INFO ] [Forwarding.pm:378] stat_name is "AGT_STATISTICS_IP405"
Apr 12 11:13:23 [RT:TRACE] [tx-art1] RT->_invoke: invoke AgtStatisticsList GetName 406
Apr 12 11:13:23 [TRACE] [RT0 tx-art1.1] [cmd] invoke AgtStatisticsList GetName 406
Apr 12 11:13:23 [TRACE] [RT0 tx-art1.1]
Apr 12 11:13:23 [RT:TRACE] [tx-art1] 0 "AGT_STATISTICS_IP406"
Apr 12 11:13:23 [INFO ] [Forwarding.pm:378] stat_name is "AGT_STATISTICS_IP406"
Apr 12 11:13:23 [RT:TRACE] [tx-art1] RT->_invoke: invoke AgtStatisticsList GetName 407
Apr 12 11:13:23 [TRACE] [RT0 tx-art1.1] [cmd] invoke AgtStatisticsList GetName 407
Apr 12 11:13:23 [RT:TRACE] [tx-art1] 0 "AGT_STATISTICS_IP412"
Apr 12 11:13:23 [INFO ] [Forwarding.pm:378] stat_name is "AGT_STATISTICS_IP412"
Apr 12 11:13:23 [RT:TRACE] [tx-art1] RT->_invoke: invoke AgtStatisticsList GetName 413
Apr 12 11:13:24 [RT:TRACE] [tx-art1] 0 "AGT_STATISTICS_IP416"
Apr 12 11:13:24 [INFO ] [Forwarding.pm:378] stat_name is "AGT_STATISTICS_IP416"
Apr 12 11:13:24 [RT:TRACE] [tx-art1] RT->_invoke: invoke AgtStatisticsList GetName 417
Apr 12 11:13:24 [TRACE] [RT0 tx-art1.1] [cmd] invoke AgtStatisticsList GetName 417
Apr 12 11:13:24 [TRACE] [RT0 tx-art1.1]
Apr 12 11:13:24 [RT:TRACE] [tx-art1] 0 "AGT_STATISTICS_IP417"
Apr 12 11:13:24 [INFO ] [Forwarding.pm:378] stat_name is "AGT_STATISTICS_IP417"
Apr 12 11:13:24 [RT:TRACE] [tx-art1] RT->_invoke: invoke AgtStatisticsList GetName 418
Apr 12 11:13:24 [TRACE] [RT0 tx-art1.1] [cmd] invoke AgtStatisticsList GetName 418
Apr 12 11:13:24 [TRACE] [RT0 tx-art1.1]
Apr 12 11:13:24 [RT:TRACE] [tx-art1] 0 "AGT_STATISTICS_IP418"
Apr 12 11:13:24 [INFO ] [Forwarding.pm:378] stat_name is "AGT_STATISTICS_IP418"
Apr 12 11:13:24 [RT:TRACE] [tx-art1] RT->_invoke: invoke AgtStatisticsList GetName 419

Perl Programming © 2008 Learning Enterprises, Inc.


215

Apr 12 11:13:24 [TRACE] [RT0 tx-art1.1] [cmd] invoke AgtStatisticsList GetName 419
Apr 12 11:13:24 [TRACE] [RT0 tx-art1.1]
Apr 12 11:13:24 [RT:TRACE] [tx-art1] 0 "AGT_STATISTICS_IP419"
Apr 12 11:13:24 [INFO ] [Forwarding.pm:378] stat_name is "AGT_STATISTICS_IP419"
Apr 12 11:13:24 [RT:TRACE] [tx-art1] RT->_invoke: invoke AgtStatisticsList GetName 420
Apr 12 11:13:24 [TRACE] [RT0 tx-art1.1] [cmd] invoke AgtStatisticsList GetName 420
Apr 12 11:13:24 [TRACE] [RT0 tx-art1.1]
Apr 12 11:13:24 [RT:TRACE] [tx-art1] 0 "AGT_STATISTICS_IP420"
Apr 12 11:13:24 [INFO ] [Forwarding.pm:378] stat_name is "AGT_STATISTICS_IP420"
Apr 12 11:13:24 [INFO ] [Forwarding.pm:446] R0 POST TEST MEASUREMENTS FOR
REFERENCE CONFIG
Apr 12 11:13:24 [TRACE] [R0 mohawk] [cmd] show chassis routing-engine
Apr 12 11:13:24 [TRACE] [R0 mohawk] Routing Engine status:
Apr 12 11:13:24 [TRACE] [R0 mohawk] Slot 0:
Apr 12 11:13:24 [TRACE] [R0 mohawk] Current state Master
Apr 12 11:13:24 [TRACE] [R0 mohawk] Election priority Master (default)
Apr 12 11:13:24 [TRACE] [R0 mohawk] Temperature 33 degrees C / 91 degrees F
Apr 12 11:13:24 [TRACE] [R0 mohawk] CPU temperature 34 degrees C / 93
degrees F
Apr 12 11:13:24 [TRACE] [R0 mohawk] DRAM 2048 MB
Apr 12 11:13:24 [TRACE] [R0 mohawk] Memory utilization 21 percent
Apr 12 11:13:24 [TRACE] [R0 mohawk] CPU utilization:
Apr 12 11:13:24 [TRACE] [R0 mohawk] User 0 percent
Apr 12 11:13:24 [TRACE] [R0 mohawk] Background 0 percent
Apr 12 11:13:24 [TRACE] [R0 mohawk] Kernel 3 percent
Apr 12 11:13:24 [TRACE] [R0 mohawk] Interrupt 0 percent
Apr 12 11:13:24 [TRACE] [R0 mohawk] Idle 97 percent
Apr 12 11:13:24 [TRACE] [R0 mohawk] Model RE-4.0
Apr 12 11:13:24 [TRACE] [R0 mohawk] Serial ID P11123907179
Apr 12 11:13:24 [TRACE] [R0 mohawk] Start time 2007-04-10 15:49:21 PDT
Apr 12 11:13:24 [TRACE] [R0 mohawk] Uptime 1 day, 19 hours, 24 minutes
Apr 12 11:13:24 [TRACE] [R0 mohawk] Load averages: 1 minute 5 minute 15
minute
Apr 12 11:13:24 [TRACE] [R0 mohawk] 0.04 0.04 0.00
Apr 12 11:13:24 [TRACE] [R0 mohawk] Routing Engine status:
Apr 12 11:13:24 [TRACE] [R0 mohawk] Slot 1:
Apr 12 11:13:24 [TRACE] [R0 mohawk] Current state Backup
Apr 12 11:13:24 [TRACE] [R0 mohawk] Election priority Backup (default)
Apr 12 11:13:24 [TRACE] [R0 mohawk] Temperature 32 degrees C / 89 degrees F
Apr 12 11:13:24 [TRACE] [R0 mohawk] CPU temperature 32 degrees C / 89
degrees F
Apr 12 11:13:24 [TRACE] [R0 mohawk] DRAM 2048 MB
Apr 12 11:13:24 [TRACE] [R0 mohawk] Memory utilization 14 percent
Apr 12 11:13:24 [TRACE] [R0 mohawk] CPU utilization:
Apr 12 11:13:24 [TRACE] [R0 mohawk] User 0 percent
Apr 12 11:13:24 [TRACE] [R0 mohawk] Background 0 percent
Apr 12 11:13:24 [TRACE] [R0 mohawk] Kernel 0 percent
Apr 12 11:13:24 [TRACE] [R0 mohawk] Interrupt 0 percent
Apr 12 11:13:24 [TRACE] [R0 mohawk] Idle 100 percent

Perl Programming Copyright 2008, Learning Enterprises, Inc.


216 Module 5

Apr 12 11:13:24 [TRACE] [R0 mohawk] Model RE-4.0


Apr 12 11:13:24 [TRACE] [R0 mohawk] Serial ID P11123907193
Apr 12 11:13:24 [TRACE] [R0 mohawk] Start time 2007-04-03 13:10:53 PDT
Apr 12 11:13:24 [TRACE] [R0 mohawk] Uptime 8 days, 22 hours, 2 minutes,
25 seconds
Apr 12 11:13:24 [INFO ] [Forwarding.pm:809] CHECKPOINT: Changing packetsize to 385
[mohawk tx-art1] [ID:00233]
Apr 12 11:13:24 [INFO ] PORT HANDLES :
Apr 12 11:13:24 [RT:TRACE] [tx-art1] RT->_invoke: invoke AgtProfileList ListHandlesBy-
Type AGT_CONSTANT_PROFILE
Apr 12 11:13:24 [TRACE] [RT0 tx-art1.1] [cmd] invoke AgtProfileList ListHandlesByType
AGT_CONSTANT_PROFILE
Apr 12 11:13:24 [TRACE] [RT0 tx-art1.1]
Apr 12 11:13:24 [RT:TRACE] [tx-art1] 0 {1 2}
Apr 12 11:13:24 [RT:TRACE] [tx-art1] RT->_invoke: invoke AgtStreamGroupList ListHandles
Apr 12 11:13:24 [TRACE] [RT0 tx-art1.1] [cmd] invoke AgtStreamGroupList ListHandles
Apr 12 11:13:24 [TRACE] [RT0 tx-art1.1]

<continues here>

Perl Programming © 2008 Learning Enterprises, Inc.


217

8.12 Perl Debugger


1. Getting Information About the Debugger
Information on how to use the debugger is found by typing at your command line:

perldoc perldebug

Here is a sample of the output:

NAME
perldebug - Perl debugging

DESCRIPTION
First of all, have you tried using the -w switch?

The Perl Debugger


If you invoke Perl with the -d switch, your script runs under the Perl
source debugger. This works like an interactive Perl environment,
prompting for debugger commands that let you examine source code, set
breakpoints, get stack backtraces, change the values of variables, etc.
This is so convenient that you often fire up the debugger all by itself
just to test out Perl constructs interactively to see what they do. For
example:

$ perl -d -e 42

In Perl, the debugger is not a separate program the way it usually is in


the typical compiled environment. Instead, the -d flag tells the
compiler to insert source information into the parse trees it’s about to
hand off to the interpreter. That means your code must first compile
correctly for the debugger to work on it. Then when the interpreter
starts up, it preloads a special Perl library file containing the
debugger.

The program will halt right before the first runtime executable
statement (but see below regarding compile-time statements) and ask you
to enter a debugger command. Contrary to popular expectations, whenever
the debugger halts and shows you a line of code, it always displays the
line it’s about to execute, rather than the one it has just executed.

Any command not recognized by the debugger is directly executed


(eval’d) as Perl code in the current package. (The debugger uses the
DB package for keeping its own state information.)

Perl Programming Copyright 2008, Learning Enterprises, Inc.


218 Module 5

For any text entered at the debugger prompt, leading and trailing
whitespace is first stripped before further processing. If a debugger
command coincides with some function in your own program, merely precede
the function with something that doesn’t look like a debugger command,
such as a leading ; or perhaps a +, or by wrapping it with
parentheses or braces.

<continues here>
----------------------------------------

2. Entering and Exiting the Debugger


To invoke the Perl debugger, use the -d switch. It allows you to examine your program
in an interactive-type environment after it has successfully compiled. After each line, the
script will stop and ask for a command. The line you will be looking at is the next line that
will be executed, not the previous one. The prompt contains the current package, function,
file and line number, and the current line. Following is a list of the debug commands.
Once you start the debugger, all the debugging commands are listed by typing h at the
debug prompt or h h if you can’t read what is displayed.
To exit the debugger, type q for quit or R for restart.

$ perl -de 0

Loading DB routines from $RCSfile: perldb.pl,v $$Revision: 4.0.1.2


$$Date: 91/11/05 17:55:58 $
Emacs support available.
Enter h for help.
DB<4> h
List/search source lines: Control script execution:
l [ln|sub] List source code T Stack trace
- or . List previous/current line s [expr] Single step [in expr]
v [line] View around line n [expr] Next, steps over subs
f filename View source in file <CR/Enter> Repeat last n or s
/pattern/ ?patt? Search forw/backw r Return from subroutine
M Show module versions c [ln|sub] Continue until position

Debugger controls: L List break/watch/actions


o [...] Set debugger options t [expr] Toggle trace [trace expr]
<[<]|{[{]|>[>] [cmd] Do pre/post-prompt b [ln|event|sub] [cnd] Set breakpoint
! [N|pat] Redo a previous command B ln|* Delete a/all breakpoints
H [-num] Display last num commands a [ln] cmd Do cmd before line
= [a val] Define/list an alias A ln|* Delete a/all actions
h [db_cmd] Get help on command w expr Add a watch expression
h h Complete help page W expr|* Delete a/all watch
exprs
|[|]db_cmd Send output to pager ![!] syscmd Run cmd in a subprocess
q or ^D Quit R Attempt a restart

Data Examination: expr Execute perl code, also see: s,n,t expr
x|m expr Evals expr in list context, dumps the result or lists

Perl Programming © 2008 Learning Enterprises, Inc.


219

methods.
p expr Print expression (uses script's current package).
S [[!]pat] List subroutine names [not] matching pattern
V [Pk [Vars]] List Variables in Package. Vars can be ~pattern or !pattern.
X [Vars] Same as "V current_package [Vars]". i class inheritance
tree.
y [n [Vars]] List lexicals in higher scope <n>. Vars same as V.
e Display thread id E Display all thread ids.

For more help, type h cmd_letter, or run man perldebug for all docs.

3. Debugger Commands
Getting out:
q Exits debugger.
R Restarts debugging session

Getting help:
h Lists help messages for all debugger commands.
hh More detailed help
hp Lists a help message for debugger command p.

Listing parts of a script:


l Lists 10 lines of the program.
l8 Lists line 8.
l 5–10 Lists lines 5 through 10.
l greetme Lists statements in subroutine, greetme.
L Lists the next line to execute.
w7 Lists a window of lines containing specified line 7. Lists 3 lines before the
specified lines and fills the window with lines after it.
/^abc/ Searches forward for regular expression abc, where abc is at the beginning of
the line.
?abc? Searches backward for regular expression abc.
S Lists all subroutines in the program by package name, two colons and the name
of the subroutine.
r Executes the remainder of statements in the current subroutine and then dis-
plays the line immediately after the subroutine call.

Stepping line by line:


s Single step a line at a time through the script.
n Like s but executes subroutine calls without stepping through them.
Enter Pressing the Enter key causes the previous s or n command to be repeated.
. Repeats the last line executed.
– Repeats all lines preceding the current one.
r Conitinues until the currently executing subroutine returns and displays the return
value and type after returning.

Perl Programming Copyright 2008, Learning Enterprises, Inc.


220 Module 5

Getting out of the debugger:


q Quit the debugger.
<Ctrl>-d Quit the debugger.
R Restart the debugger and a new session.

Setting Breakpoints:
Breakpoints allow you to set a place where the program will stop so that you can examine
what’s going on. Once you are satisfied that at least some of the statements are executing
correctly you can let them execute automatically and stop at the parts of the program that
need to be examined more closely. You can set breakpoints at certain lines so that the
debugger stops and waits for you to issue debugger commands. There are several ways to
set breakpoints, including by line number and by line number if some condition is met (such
as a variable having a certain value). All of them are explained in the perldebug man page.

b 45 Sets break point to line 45. Type c to continue and the program will stop exe-
cution at line 45.
c Continue execution.
b greetme Sets break point to subroutine greetme.
b $x > 10 Triggers a breakpoint only if the condition is true.
w Creates a window around the breakpoint and marks the line where the break-
point is found; e.g., 10==>b (breakpoint is at line 10).
d Deletes the breakpoint on the line about to execute.
d 12 Deletes the breakpoint at line 12.
D Deletes all breakpoints.

Displaying value of symbols, variables, expressions:


X name Displays the value of any variables called name in the current package. Vari-
able names are NOT preceded by their identifying funny character; e.g., use
name rather than $name or @name.
V package Displays all variables (symbols) within a package.
p $x + 3 Evaluates and prints the expression. Same as "print {DB::OUT} expr" in cur-
rent package.
x %student Evals expression in list context, dumps the result.

Tracing:
T Produces a stack backtrace listing of what subroutines were called.
t Toggles trace mode.

Aliases:
= Lists all aliases.

Perl Programming © 2008 Learning Enterprises, Inc.


221

= ph print "$hashref–>{Science}–>{Lou}" ph is an alias for printing a hash value


4. Using the Debugger: Examples

Starting up, viewing symbols

1 $ perl -de 0
Loading DB routines from perl5db.pl version 1.28
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(-e:1): 0
2 DB<1> @colors = qw( red blue green yellow orange);

3 DB<2> $colors = "aqua";

4 DB<3> X colors
$colors = 'aqua'
@colors = (
0 'red'
1 'blue'
2 'green'
3 'yellow'
4 'orange'
)
DB<4>
-------------------------------------------------------------

History command
DB<4> H
3: X colors
2: $colors = "aqua";
1: @colors = qw( red blue green yellow orange);

-------------------------------------------------------------
Listing lines and Stepping
1 perl -d random.plx
Loading DB routines from perl5db.pl version 1.28
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

2 main::(random.plx:1): $saying = "An apple a day ";


DB<1> l
1==> $saying = "An apple a day ";
2: @sayings=( $saying,
3 "A stitch in time",
4 "Too many cooks ",

Perl Programming Copyright 2008, Learning Enterprises, Inc.


222 Module 5

5 "A bird in the hand ",


6 "To be a friend ",
7 );
8
9
10: randomize(\@sayings);
DB<1> s
main::(random.plx:2): @sayings=( $saying,
main::(random.plx:3): "A stitch in time",
main::(random.plx:4): "Too many cooks ",
main::(random.plx:5): "A bird in the hand ",
main::(random.plx:6): "To be a friend ",
main::(random.plx:7): );
DB<1> l
2==> @sayings=( $saying,
3 "A stitch in time",
4 "Too many cooks ",
5 "A bird in the hand ",
6 "To be a friend ",
7 );
8
9
10: randomize(\@sayings);
11
DB<1>

------------------------------------------------------------
Viewing arrays, hashes with X and x
(Note: You cannot view lexical(’my’) variables with X or x.)
-----------------------------------
(The Script)
#!/usr/bin/perl
1 $colors = "Prussian blue";
2 @colors = ( 'red', 'blue', 'green', 'yellow', 'orange');
3 %colors = ( "flag" => [ "red", "white", "blue" ],
"sky" => [ qw(purple red ) ],
"clothes" => { "coat"=>"blue",
"pants"=>"black",
"hat" =>"green",
},
"house" => "yellow",
);
print "The sea is $colors.\n";
print "The colors in his palette are ",join(",",@colors),".\n";
print "His hat is $colors{'clothes'}->{'hat'}.\n";
(Output)
The sea is Prussian blue.
The colors in his palette are red,blue,green,yellow,orange.
His hat is green.

Perl Programming © 2008 Learning Enterprises, Inc.


223

4 $ perl -d debug.plx

Loading DB routines from perl5db.pl version 1.28


Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(debug.plx:2): $colors = 'Prussian blue';


5 DB<1> l
2==> $colors = 'Prussian blue';
3: @colors = ( 'red', 'blue', 'green', 'yellow', 'orange');
4: %colors = ( "flag" => [ "red", "white", "blue" ],
5 "sky" => [ qw(purple red ) ],
6 "clothes" => { "coat"=>"blue",
7 "pants"=>"black",
8 "hat" =>"green",
9 },
10 "house" => "yellow",
11 );
DB<1>
...
6 DB<11> X colors
$colors = 'Prussian blue'
@colors = (
0 'red'
1 'blue'
2 'green'
3 'yellow'
4 'orange'
)
%colors = (
'clothes' => HASH(0x189f524)
'coat' => 'blue'
'hat' => 'green'
'pants' => 'black'
'flag' => ARRAY(0x189f500)
0 'red'
1 'white'
2 'blue'
'house' => 'yellow'
'sky' => ARRAY(0x1884378)
0 'purple'
1 'red'
)
7 DB<12> x %colors
0 'house'
1 'yellow'
2 'sky'
3 ARRAY(0x1884378)
0 'purple'

Perl Programming Copyright 2008, Learning Enterprises, Inc.


224 Module 5

1 'red'
4 'clothes'
5 HASH(0x189f524)
'coat' => 'blue'
'hat' => 'green'
'pants' => 'black'
6 'flag'
7 ARRAY(0x189f500)
0 'red'
1 'white'
2 'blue'

------Better output if you use a reference to the hash-------

8 DB<13> x \%colors
0 HASH(0x12d2c)
'clothes' => HASH(0x189f524)
'coat' => 'blue'
'hat' => 'green'
'pants' => 'black'
'flag' => ARRAY(0x189f500)
0 'red'
1 'white'
2 'blue'
'house' => 'yellow'
'sky' => ARRAY(0x1884378)
0 'purple'
1 'red'
DB<14>
------------------------------------------------------------
Evaluating Expressions and Printing Values
Enter h or `h h' for help, or `man perldebug' for more help.

main::(regex.plx:2): $pets = "dog, cat, bird, pig";


DB<1> l
2==> $pets = "dog, cat, bird, pig";
3: print "original pet list: $pets\n";
4: $pets =~/(.+), (.+)/;
5
6: $pets =~ s/$2/turtle/;
7
8: print "new pet list: $pets\n";
9
10
11
DB<6> s
main::(regex.plx:3): print "original pet list: $pets\n";
DB<6> s
original pet list: dog, cat, bird, pig
main::(regex.plx:4): $pets =~/(.+), (.+)/; <---Capturing

Perl Programming © 2008 Learning Enterprises, Inc.


225

DB<6> s
main::(regex.plx:6): $pets =~ s/$2/turtle/;
DB<6> p $pets
dog, cat, bird, pig
DB<7> p $1 <-----Why so many captured in $1?
dog, cat, bird
DB<8> p $2
pig
DB<9> s
main::(regex.plx:8): print "new pet list: $pets\n";
DB<9> s
new pet list: dog, cat, bird, turtle
Debugged program terminated. Use q to quit or R to restart,
use O inhibit_exit to avoid stopping after program termination,
h q, h R or h O to get additional info. 11

----------------------------------------

Step and Next

------next jumps over the subroutine -------


Enter h or `h h' for help, or `man perldebug' for more help.

main::(random.plx:1): $saying = "An apple a day ";


DB<1> s
main::(random.plx:2): @sayings=( $saying,
main::(random.plx:3): "A stitch in time",
main::(random.plx:4): "Too many cooks ",
main::(random.plx:5): "A bird in the hand ",
main::(random.plx:6): "To be a friend ",
main::(random.plx:7): );

1 DB<1> s
main::(random.plx:10): randomize(\@sayings);
2 DB<1> n <------Jump over subroutine statements
1
A stitch in time
2
Too many cooks
0
An apple a day
2
Too many cooks
Debugged program terminated. Use q to quit or R to restart,
use O inhibit_exit to avoid stopping after program termination,
h q, h R or h O to get additional info.

--------Stepping through each line in the loop--------

Perl Programming Copyright 2008, Learning Enterprises, Inc.


226 Module 5

DB<1> s
main::(random.plx:10): randomize(\@sayings);
DB<1> s
main::randomize(random.plx:13): my $ptr = shift;
DB<1> s
main::randomize(random.plx:14): $n=0;
DB<1> s
main::randomize(random.plx:15): while ( $n < $#$ptr ){
DB<1> s
main::randomize(random.plx:16): $i= int(rand(5)) ;
DB<1> s
main::randomize(random.plx:17): print "$i\n";
DB<1> s
2
main::randomize(random.plx:18): print $ptr->[$i],"\n";
DB<1> s
Too many cooks

-------------------------------------------
Break points

Loading DB routines from perl5db.pl version 1.28


Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(random.plx:1): print "What is your favorite saying? ";


DB<1> s
main::(random.plx:2): chomp($saying=<STDIN>);
DB<1> What is your favorite saying?
an apple a day
main::(random.plx:3): @sayings=( $saying,
main::(random.plx:4): "A stitch in time",
main::(random.plx:5): "Too many cooks ",
main::(random.plx:6): "A bird in the hand ",
main::(random.plx:7): "To be a friend ",
main::(random.plx:8): );
DB<1> l
3==> @sayings=( $saying,
4 "A stitch in time",
5 "Too many cooks ",
6 "A bird in the hand ",
7 "To be a friend ",
8 );
9: print "\nNow we will print random sayings:\n";
10: print "-" x 35, "\n";
11: randomize(\@sayings);
12
DB<1> b 11 <----Stop execution at line 11
DB<2> c <----Continue to line 11

Perl Programming © 2008 Learning Enterprises, Inc.


227

Now we will print random sayings:


-----------------------------------
main::(random.plx:11): randomize(\@sayings);
DB<2> l
11==>b randomize(\@sayings);
12
13 sub randomize{
14: my $ptr = shift;
15: $n=0;
16: while ( $n < $#$ptr ){
17: $i= int(rand(5)) ;
18 # print "$i\n";
19: print $ptr->[$i],"\n";
20: $n++;
DB<2> b 16
DB<3> c
main::randomize(random.plx:16): while ( $n < $#$ptr ){
DB<3> l
16==>b while ( $n < $#$ptr ){
17: $i= int(rand(5)) ;
18 # print "$i\n";
19: print $ptr->[$i],"\n";
20: $n++;
21 }
22: print "\n";
23 }
DB<3> b 22
DB<4> c
an apple a day
an apple a day
A bird in the hand
Too many cooks
main::randomize(random.plx:22): print "\n";
DB<4>
-------------------------------
List all breakpoints
DB<4> L
random.plx:
11: randomize(\@sayings);
break if (1)
16: while ( $n < $#$ptr ){
break if (1)
22: print "\n";
break if (1)
DB<4>
----------------------
Delete breakpoints

DB<5> B 22
DB<6> L

Perl Programming Copyright 2008, Learning Enterprises, Inc.


228 Module 5

random.plx:
11: randomize(\@sayings);
break if (1)
16: while ( $n < $#$ptr ){
break if (1)
DB<6> B *
Deleting all breakpoints...

--------------------------------

Pattern Matching
/pattern/ forward search for pattern
?pattern? backward search for pattern

Loading DB routines from perl5db.pl version 1.28


Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(student.plx:4): $ptr1 = Student->new(); # Create new students


DB<1> l
4==> $ptr1 = Student->new(); # Create new students
5: $ptr2 = Student->new();
6: $ptr3 = Student->new();
7
8: $ptr1->set("Name", "Jody Rogers"); # Set data for object
9: $ptr1->set("Major", "Law");
10
11: $ptr2->set("Name", "Christian Dobbins");
12: $ptr2->set("Major", "Drama");
13
DB<1> /Major
15: $ptr3->set("Major", "Art");

DB<2> ?Jody
8: $ptr1->set("Name", "Jody Rogers"); # Set data for object

DB<3>

--------------------------------------
Actions

perl -d regex.plx

Loading DB routines from perl5db.pl version 1.28


Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

Perl Programming © 2008 Learning Enterprises, Inc.


229

main::(regex.plx:2): $pets = "dog, cat, bird, pig";


DB<1> l
2==> $pets = "dog, cat, bird, pig";
3: print "original pet list: $pets\n";
4: $pets =~/(.+?), (.+?),/;
5
6: $pets =~ s/$2/turtle/;
7
8: print "new pet list: $pets\n";
9
10
11
DB<1> a 6 $pets =~ s/$2/cow/;
DB<2> c
original pet list: dog, cat, bird, pig
new pet list: dog, turtle, bird, cow
Debugged program terminated. Use q to quit or R to restart,
use O inhibit_exit to avoid stopping after program termination,
h q, h R or h O to get additional info.
DB<2> L
regex.plx:
6: $pets =~ s/$2/turtle/;
action: $pets =~ s/$2/turtle/;
---------------------------------------------

Tracing

main::(random.plx:1): print "What is your favorite saying? ";


DB<1> s
main::(random.plx:2): chomp($saying=<STDIN>);
DB<1> What is your favorite saying?
An apple a day
main::(random.plx:3): @sayings=( $saying,
main::(random.plx:4): "A stitch in time",
main::(random.plx:5): "Too many cooks ",
main::(random.plx:6): "A bird in the hand ",
main::(random.plx:7): "To be a friend ",
main::(random.plx:8): );
DB<1> t
Trace = on
DB<1> l
3==> @sayings=( $saying,
4 "A stitch in time",
5 "Too many cooks ",
6 "A bird in the hand ",
7 "To be a friend ",
8 );
9: print "\nNow we will print random sayings:\n";
10: print "-" x 35, "\n";

Perl Programming Copyright 2008, Learning Enterprises, Inc.


230 Module 5

11: randomize(\@sayings);
12
DB<1> s
main::(random.plx:9): print "\nNow we will print random sayings:\n";
DB<1> s

Now we will print random sayings:


main::(random.plx:10): print "-" x 35, "\n";
DB<1> s
-----------------------------------
main::(random.plx:11): randomize(\@sayings);
DB<1> s
main::randomize(random.plx:14): my $ptr = shift;
DB<1> s
main::randomize(random.plx:15): $n=0;
DB<1> s
main::randomize(random.plx:16): while ( $n < $#$ptr ){
DB<1> c
main::randomize(random.plx:17): $i= int(rand(5)) ;
main::randomize(random.plx:18): print $ptr->[$i],"\n";
Too many cooks
main::randomize(random.plx:19): $n++;
main::randomize(random.plx:17): $i= int(rand(5)) ;
main::randomize(random.plx:18): print $ptr->[$i],"\n";
A bird in the hand
main::randomize(random.plx:19): $n++;
main::randomize(random.plx:17): $i= int(rand(5)) ;
main::randomize(random.plx:18): print $ptr->[$i],"\n";
To be a friend
main::randomize(random.plx:19): $n++;
main::randomize(random.plx:17): $i= int(rand(5)) ;
main::randomize(random.plx:18): print $ptr->[$i],"\n";
Too many cooks
main::randomize(random.plx:19): $n++;
main::randomize(random.plx:21): print "\n";

Debugged program terminated. Use q to quit or R to restart,


use O inhibit_exit to avoid stopping after program termination,
h q, h R or h O to get additional info.

Perl Programming © 2008 Learning Enterprises, Inc.


231

4. Student Debugging Lab


Using the debugger, see if you can find the problem with this program. Then use
"pod" to document the program so that others can understand how it works.
---------------------------------------------------
(The Script)
#!/usr/bin/perl -w
use strict;
my $arg = $ARGV[0] || '-c20';

if ($arg =~ /^\-(c|f)((\-|\+)*\d+(\.\d+)*)$/) {
my ($deg, $num) = ($1, $2);
my ($in, $out) = ($num, $num);
if ($deg eq 'c') {
$deg = 'f';
$out = &c2f($num);
} else {
$deg = 'c';
$out = &f2c($num);
}
$out = sprintf('%0.2f', $out);
$out =~ s/^((\-|\+)*\d+)\.0+$/$1/;
print "$out $deg\n";
} else {
print "Usage: $0 -[c|f] num\n";
}
exit;

sub f2c {
my $f = shift;
my $c = 5 * $f - 32 / 9;
return $c;
}

sub c2f {
my $c = shift;
my $f = 9 * $c / 5 + 32;
return $f;
}

Perl Programming Copyright 2008, Learning Enterprises, Inc.


232 Module 5

Perl Programming © 2008 Learning Enterprises, Inc.

Вам также может понравиться