Web Solutions-Open Source CPAN 561
Lecture 7: Object Oriented Perl
Perl allows to package code into a separate files called modules. The extension of such files should be (.pm), and it should be saved in a standard directory where Perl can look for it. The module name is related to the name of the text file that contains this module. A Perl library is is a collection of code intended for reusable Perl code.
Pragmas are special kinds of Perl modules that affect how Perl compiles and runs the script. Following is a list of some Pragmas that you can use:
Pragma Name / Description / Examplesubs / Pre declares sub names / use subs qw (sub1);
warnings / Controls optional warnings / use warnings;
no warnings;
use warnings "all";
strict / Restricts unsafe constructs. You can use no strict to turn restricting off for certain block of code. / use strict;
no strict;
integer / use integer arithmetic instead of floating point. / use integer;
diagnostics / Forces verbose warning diagnostics / use diagnostics;
use diagnostics -verbose;
enable diagnostics;
disable diagnostics;
constant / Declares a constant. / use constant TAX => 0.015;
The following rules are important to understand how to work with Object Oriented Perl :
· To create a class, build a package:
In perl package have the features to act like a class. The class starts with the statement:
package classname;
And the last statement should be
1;
· To create a method, write a subroutine:
The only catch with writing such methods is that the name of the class is passed as the first argument to the method.
Perl has two types of methods: static and virtual. A static method expects a class name as the first argument. A virtual method expects a reference to an object as the first argument.
Since static method uses the class name, the method functionality applies to the entire class. Because static methods know which class they belong, first argument is ignored in general.
There are two ways to invoke a method for an object: by making a reference to an object (virtual) or explicitly referring to the class name (static).
· To create an object, bless a referent:
An object can be of any Perl existing variables types. You can create an object as you would create any other Perl variables. The only difference is that you need to use the build in function bless to make a variable as belonging to a particular class. bless takes two arguments: a reference to the variable to be marked as an object and a string representing the class name.
· To access a module, import it:
To a module, imported using the function use. Perl will search for this module in a special set of directories called the @INC array. If you want to add a directory to this array, you can push a string representing the directory's full path into @INC. For example:
BEGIN { push @INC, "C:/perllib/test"}
There is a better way using the use lib directive:
use lib "c:/perllib/test";
The use function is used to import the code at compile time. If you want to import the code at run time, then use require function.
When you An object can be of any Perl existing variables types. You can create an object as you would create any other Perl variables. The only difference is that you need to use the build in function bless to make a variable as belonging to a particular class. bless takes two arguments: a reference to the variable to be marked as an object and a string representing the class name.
Constructor:
The constructor of a class is a method called new. This method is called whenever you create a new object. The constructor is a static method.
If we have a module called firstClass, then we can create an object using the statement:
$Ob = new firstClass();
or we can use the statement:
$Ob = firstClass::new();
The arguments to a new method are called instance variables; they allow you to customize each object as it is created. For example, assume that we want firstClass to have 2 instance variables: name and address, then we can write the constructor as follows:
sub new
{
# the class name is passed as the first parameter
my ($className)=@_;
# this instance variable are passed as $_[1], $_[2], and so on
my $self=bless { _name =>$_[1],
_address =>$_[2],
},$className;
return $self;
}
We passed to the bless function two parameters: an anonymous hash with the class instance variables, and the class name. The bless function will turn the anonymous hash into an object of class firstClass and return the resultant object.
To access any of the instance variables of firstClass, we have to create an object of this class and then access these member variables:
$Ob = new firstClass();
print $Ob->{_name};
print $Ob->{_address};
You can also provide set/get methods for each instance member variables:
sub getName
{
return $_[0]->{_name};
}
sub getAddress
{
return $_[0]->{_address};
}
sub setName
{
my ($this,$name)=@_;
return $this->{_name}= $name if $name;
}
And we can access the instance variables using these methods:
$Ob->setName("Jonh");
print $Ob->getName();
Destructor:
Perl uses simple, reference based garbage collection system that keep track of references to an object. When the last reference to an object is freed from the memory, the object is automatically destroyed.
If you want to perform certain functionality before the object is freed, you can define a DESTROY() method in your class.
Setting up a module:
Create a standard library directory and save your module in it.
Inform Perl interpreter of your module existing. One of the methods is to use the use lib directive where you specify the path of your standard library directory. For example if you have chosen to create a folder named perllib under the main directory (C:), then you can inform Perl of the existing of modules inside this folder by using the statement:
use lib “c:/perllib”;
Using the CPAN:
Developers from all over the world share their own modules by distributing them via the Comprehensive Perl Archive Network. Other developers can access and download these modules for free.
Before you create a new module, is worth searching the CPAN for an existing ones. One of the useful site for this purpose is http://www.perl.com/CPAN.
To search and install modules from the CPAN, you can use one of the following two methods:
· Using Perl Package Manager:
This is the easiest way to install modules from the CPAN. When you install Active state Perl, it comes with the tool PPM. To start the tool under Windows, select Start-> program file-> active state->PPM. Under UNIX, type ppm at the shell prompt ( You may need to add perl/bin to the SYSTEM PATH).
To find help about the commands used with PPM, type the following command:
ppm> help
To get a list of all the available packages, use the command:
ppm> search *
To list all the packages previously installed , use the command:
ppm> query *
Once you find a package, you can install it using the command:
ppm> install package_name
To exist , type the command:
ppm> exit
By default ActiveState repository is the default repository of perl modules. You can view all the available repositories using the command
ppm> repository
To add a new site to your repository , use the command
ppm> repository add [name] url
name is optional and represent the name that will be assigned to this repository. To delete a repository by its name or its number in the list, use the command
ppm> repository delete <name or num>
For more details about PPM and all of its commands , see the documentation of active state perl.
· Using CPAN.pm module. It can be installed using the following command:
c:/perl/bin> perl -MCAPN -e shell
You can either select manual or automatic installation.
Once you have this module installed you will see at the prompt:
cpan>
You cannow search and install Perl modules form the CPAN.
Once you run the above command, you can view the module help by typing help on the command line as follows:
cpan> help
Once you find a module, you can install it using the install command. For example :
cpan> installpackage_name
The installed modules will be stored under a folder called .cpan and you may need provide the path of your new installed package using use lib statement in your script.
Inheritance:
Perl supports multiple inheritance through the use of the global array @ISA. This array indicates in which classes to search for a method definition if one is not found in the current class definition. For example:
package secondClass;
use vars qw(@ISA);
@ISA = qw(firstClass);
use firstClass;
The function qw() is used to specify a string list. It helps you keep track of quotes and backslashes.
Only methods are inherited automatically in Perl. Instance variables are not inherited directly unless you arrange for that. The inherited class is called the super class or the base class. The class that is inheriting the base class is called the derived class or the subclass.
Constructors and destructors are inherited as any regular Perl method. If the derived class has no constructor, then Perl will search the base classes for matching one.
Unlike other Object Oriented Programming languages, there is no hierarchy calling of constructors or destructors, unless they are coded to so. There is no compile time checker for inheritance and implementation of derived classes.
If a method is found in both the derived class and the base class, then this method is known as been overridden.
Examples:
Ex1:
In this example we will create a simple Perl module called firstClass.pm:
package firstClass;
use strict;
sub new
{
my ($className)=@_;
my $self=bless { _name=>$_[1] , _address =>$_[2] },$className;
return $self;
}
sub getName
{
return $_[0]->{_name};
}
sub getAddress
{
return $_[0]->{_address};
}
sub setName
{
my ($this,$name)=@_;
return $this->{_name}= $name if $name;
}
sub setAddress
{
my ($this,$address)=@_;
return $this->{_address}= $address if $address;
}
1;
This simple module (class) has two member variables: _name and _address. It has also set/get methods for each member variable. The constructor of this module (new) is designed to accept two arguments: the first is assigned to _name and the second is assigned to _address. bless is used to identify _name and _address as a member variables of the class firstClass. The first argument passed to bless is an anonymous has with the class member variables.
To test this module, create the folder c:/perllib/test and save the above module in it with the name firstClass.pm. After that create a Perl script called firstClassTest.cgi and store it under cgi-bin folder.
In firstClassTest.cgi we will create an object of type firstClass called obj by calling the constructor of firstClass. To make sure the new object is created , we will call get and set methods of this object .
firstClassTest.cgi
#! c:/perl/bin/perl
use strict;
use lib "C:/perllib/test";
use firstClass;
print "Content-Type:text/html\n\n";
my $obj=new firstClass("Robert","123 main strret");
print $obj->getName();
print "<br>";
print $obj->getAddress();
print "<br>";
$obj->setName("John");
print $obj->getName();
print "<br>";
print $obj->getAddress();
Following is a screenshot of the output:
Ex2:
In this example we will create a module called checkLogin.pm to validate the user login based on user name and user password. This module has two member variables _name and _password and it provide set/get methods for each of these member variables.
An object of this class will be created with a specific user name/password. The user name/password will be checked in a method called check against a hash of allowed users. This hash will be passed as an argument from the Perl program that will use this module. If the user was found in the hash, check will return true , otherwise it will return false.
CheckLogin.pm
package checkLogin;
use strict;
sub new
{
my ($className)=@_;
my $self=bless { _name =>$_[1],
_password =>$_[2],
},$className;
return $self;
}
sub getName
{
return $_[0]->{_name};
}
sub getPassword
{
return $_[0]->{_password};
}
sub setName
{
my ($this,$name)=@_;
return $this->{_name}= $name if $name;
}
sub setPassword
{
my ($this,$password)=@_;
return $this->{_password}= $password if $password;
}
sub check
{
my $this = shift;
my $result="false";
my $users=$_[0];
my($key,$value);
foreach $key (keys(%$users))
{
if (($this->{_name} eq $key) & ($this->{_password} eq $$users{$key}))
{
$result="true";
}
}
return $result;
}
1;
To make use of this module , we will create the following HTML form called checkLoginTest.html:
<html>
<head>
<title>Perl Module test</title>
</head>
<body>
<form method="post" action="http://localhost/cgi-bin/checkLoginTest.cgi">
<p>User Name:<input type="text" name="username" size="20"</p>
<p>User Password:<input type="password" name="userpassword" size="20"</p>
<p </p>
<p<input type="submit" value="Submit" name="B1"<input type="reset" value="Reset" name="B2"</p>
</form>
</body>
</html>
This form will be submitted to a Perl program called checkLoginTest.cgi:
#! c:/perl/bin/perl
use strict;
use lib "C:/perllib/test";
use checkLogin;
use CGI qw(:standard);
print "Content-Type:text/html\n\n";
my $name=param('username');
my $password=param('userpassword');
my $tt=new checkLogin($name,$password);
my %users=("john"=>"123","smith"=>"123");
my $result=$tt->check(\%users);
if ($result eq "true")
{
print "login correct";
}
else
{
print "login incorrect";
print "<br<a href=\"http://localhost/checkLogin.html\"> try again</a>";
}
In this program ,we will create an object called tt with the user name and password. Also we will hard code the eligible users into a hash called users and pass it to check method of tt object. If the user login is successful, the message login correct will be displayed, otherwise the message login incorrect will be displayed with a link to checkLoginTest.html
Following are screenshots of the output:
Ex3:db.cgi
In this example we will connect to and query MySQL Database server. To find about MYSQL database server installation and usage, see module 7-2.