Lecture21 Adv Perl Programming
Lecture21 Adv Perl Programming
Subroutines
Subroutines are part of many of the modern programming languages. C has functions and
Java has methods and Pascal has procedures and functions for defining subroutines.
Subroutines allow us to break the code into manageable pieces. Perl subroutines, like
many of the high level languages, can have input parameters, local variables, and can
return the answers back to the calling routine (eg: main). Let us start with a simple sub
routine definition.
sub name {
statements;
}
Subroutines can be called by other subroutines and subroutines can return values that can
be used by other subroutines.
sub sum {
return $a + $b;
}
$a = 12; $b = 10;
$sum = sum();
print “the sum is $sum\n”;
sub list_of_values {
return ($a,$b,$b,$a);
}
Passing Arguments
A perl subroutine can be called with a list in parenthesis. For example, we can write a
generic add function as follows.
sub add {
$tmp = 0; # this defines a global variable
foreach $_ (@_) {
$tmp += $_;
}
return $tmp;
}
In the above code @_ refers to the list passed to the function when it is called. For
example, if we call the function as: add($a,$b,$c); or add(3,4,5,6);
Then @_ = ($a,$b,$c) or @_ = (3,4,5,6)
Local variables
Perl subroutines can define local private variables. Here is an example with a local
variable.
sub product {
my ($x); # defines the local variable x
foreach $_ (@_) { $x *= $_;}
return $x;
}
You can have a list of local variables by simply expanding the list as:
my ($x, $y, @arr);
takes two command line arguments, infile.txt and outfile.txt. The number of command
line arguments is given by $#ARGV + 1 and command line arguments are named
$ARGV[0], $ARGV[1], etc. In the above example,
Here is a Perl program that reads from a file and writes to another file.
#! /usr/local/bin/perl -w
$numargs = $#ARGV + 1;
if ($numargs >= 2){
open(INFILE, $ARGV[0]);
open(OUTFILE,">$ARGV[1]");
foreach $line (<INFILE>) {
print OUTFILE $line;
}
close(INFILE);
close(OUTFILE);
}
You can run this program with > perl program.pl infile.txt outfile.txt
LWP is the Perl library for processing functions related to www activities. For example,
we can get the source code for a web page by typing
use LWP::Simple;
$_ = get($url)
Where URL refers to a string such as http://www.cs.cmu.edu and $_ is the default system
variable.
Command line arguments can be obtained as above or for command line options such as
-n 100 -t dir_name
use Getopt::Long;
$images_to_get = 20;
$directory = ".";
GetOptions("n=i" => \$images_to_get,
"t=s" => \$directory);
H(key) = value
The advantage of a hash table (compared to other data structures such as linked lists and
trees) is that finding something in a hash table is easy. We simply provide the key we are
looking for to a hash function, and the function returns a value. For example think of a
hash function that maps each string to the sum of its characters where characters are
assigned values such as ‘a’=1, ‘b’=2, .. ‘z’=26 etc. So
H(“abc”) = 1+2+3 = 6
and the string “abc” can be stored in array[6]. Of course you probably immediately notice
a problem with this approach. All permutations of the string “abc” maps to the same
value, producing what we call a “collision”. Collisions cannot be fully avoided in hash
tables, but can be minimized by selecting a “good” hash function. For example if we
choose the hash function,
Then all permutations of the string “abc” will not have the same hash code.
Hashing is a popular technique for storing and retrieving data and hash tables are
becoming popular data structures to be used in programming. Hash tables are easy to
program and are very effective in applications where searching is a major operation (eg: a
search engine). Hashing is an ideal way to store a dictionary. Major operations required
by a dictionary are updates and lookups that can be achieved in constant time or O(1)
using a hash table. Hash tables are not suitable applications that require data to be stored
in some order. Finding max, min or median is inefficient in a hash table. These operations
can be efficiently done using a sorted array.
Hashing in Perl
Perl provides facilities for hash tables. A hash variable name is preceded by a percent
sign (%). For example we can define a hash as follows.
@keyset = keys(%hash);
provides the keyset for the hash. To print all keys we can do (or simply print the keyset as
defined above)
or
print @keyset;
The value Set
Now that we know the key set, we can find the values for each key by
@valueset = values(%hash);
Each function
We can iterate over all the (key,value) pairs in the hash table using “each” function. For
example
Ex 1: Write a Perl program to store a dictionary (you can use dictionary.txt from a lab) in
a hash table. Use each word in the dictionary as the key. You may use any hash function
to compute the value. Ask the user to input a word interactively and look for the word in
the hash table. If exists print the value.
delete $hash{‘key’};
References in Perl
With the release of Perl 5, programmers now can represent complex data structures in
Perl. For example, we may want to build an array of arrays, or an array of hash tables and
many combinations of data structures. References to objects can be created using the “\”
operator. A reference to an object is much like the address operator in C. Here are some
examples.
Creating a Reference to a scalar
$num = 10;
$numref = \$num;
Dereference
Dereferencing a Reference to a scalar
$num = 10;
$numref = \$num;
print $$numref; # prints the value 10
opendir(DIR,".");
foreach $file (readdir(DIR)) {
print "$file \n";
}
close(DIR);
Here opendir opens the current directory (“.”) and pass a reference to the directory DIR to
readdir function. The code prints out all files in the current directory.
Ex 2: Write a perl program to output all files in a specific directory that contains the
substring .c (use regex)
Changing Directories
In UNIX we can use the chdir command to change a directory. For example
chdir “somedir”
changes the current directory to somedir. We can use similar code in perl programs. For
example, you can ask the user to enter a name of a directory and list all the files in that
directory as follows.
opendir(DIR,".");
foreach $file (readdir(DIR)) {
print "$file \n";
}
Every process has its own current directory. If you launch the program from the parent
process, it won’t affect the parent shell that launched the perl program.
Removing a File
This is really risky behavior. You should try not to run any program that removes files
without making sure you really want to do that. If you delete a file accidentally, your
system administrator can still find the file for you. But unless sys admin is your good
buddy this is something you want to avoid. If you want to remove a file in UNIX, you
would do
rm “guna.c”
removes the file guna.c. Perl also has an unlink function, that removes the name for a file.
Typically removing the name of a file, removes the file unless you have created hard
links for the file using link function. Here is Perl code that removes a file.
There are variations of unlink function. You can remove multiple files or all the object
files in a directory as follows.
unlink(“file1”, “file2”);
Renaming a File
A file can be renamed as follows
Modifying Permissions
The permission on a file or directory ca be modified using chmod. The following code
modifies the file permission of two files given as a list. It can be generalized to any array
of files.
foreach $file (“guna.c”, “temp.o”) {
unless chmod (O666, $file) {
warn “could not chmod the file $file \n”;
}
}
#!/usr/local/bin/perl
Ex 3 : Write a perl program that reads a file of folder names and create sub directories in
the current directory with permission for each folder set to rwx for all.
Ex 4 : Write a perl program that request the directory name and list all the files in that
directory that have file permissions rwx for Group.