Main Page Content
Camel POOP: Object Oriented Programming in Perl
Rated 4.12 (Ratings: 7) (Add your rating)
Log in to add a comment
(0 comments so far)
Want more?
- More articles in Code
- More articles by khurtwilliams
Most people are not aware of the fact that Perl has support for object-oriented programming. If you've used another object-oriented programming language such as Java or C++ or been exposed to object-orientation then object oriented programming in Perl is nothing like that. To do real useful object-oriented programming in Perl you only need to use a few simple rules as put forth by Larry Wall in Object Oriented Perl.
Object oriented programmers are familiar with the concept of object and classes but I will review that here quickly. An object is a thing that provides access to or modification of data. A class is description of the attributes of a particular kind of object and the manner in which those objects can be accessed and modified. A method is a means by which an object's data is accessed or modified. An object is an instance of a class.
An example would be a Person class in an HR system. The Person class describes the attributes of an Person such as name, address, title, social security number, id etc. A particular class instance or object would encapsulate data about a particular Person e.g. name, title, social security number, address, etc. Some methods to access that object's data would be name, address etc.
Package delivery
To create a class in Perl we first build a package. A package is a self-contained unit of user-defined variables and subroutines, which can be re-used over and over again. They provide a separate namespace within a Perl program that keeps subroutines and variables from conflicting with those in other packages.
To declare a class named Person in Perl we do:
package Person;
That's it. The scope of the package
definition extends to the end of the
file, or until another package
keyword is encountered. Not very
useful yet but on to the next
section.
There's a method to this madness
A method is a means by which an object's data is accessed or modified. In Perl a method is just a subroutine defined within a particular package. So to define a method to print our Person object we do:
sub print {
my ($self) = @_;
#print Person info
printf("Name:%s %s\n\n", $self->firstName, $self->lastName );
}
The subroutine print is now
associated with the package
Person. To call the
method print on an
Person object we use
the Perl "arrow" notation. If the
variable $khurt contains an
Person object we would
call print on that object by writing:
$khurt->print();
When the object method is invoked a reference to the object is passed in along with any other arguments. This is important since the method now has access to the object on which it to operate.
How do we create the invoking object?
Bless me father
To create an instance of a class (an
object) we need an object
constructor. This constructor is a
method defined within the package.
Most programmers choose to name this
object constructor method new but in
Perl one can use any name.
One can use any kind of Perl variable as an object in Perl. Most Perl programmers choose either references to arrays or hashes.
Let's create our constructor for our Person class using a Perl hash reference;
#constructor
sub new {
my $self = {
_firstName => undef,
_lastName => undef,
_ssn => undef,
_address => undef
};
bless $self, 'Person';
return $self;
}
What have we done? We created a
subroutine called new
associated with the package
Person. The entries of
the hash reference $self
become the attributes of our object.
We then use the bless function
on the hash reference. The
bless function take two
arguments; a reference to the
variable to be marked and a string
containing the name of the class.
This indicates that the variable now
belongs to the class
Person.
To create an instance of our Person object:
my $khurt = new Person();
We have not defined accessor methods
or done any error checking on the
input values or keys or the anonymous
hash reference but we have the start
of a Perl Person OO
framework. To make our constructor
more flexible and to make our class
inheritable (more on that later) we
can define it to use the
$class variable to bless
the hash reference.
#constructor
sub new {
my ($class) = @_;
my $self = {
_firstName => undef,
_lastName => undef,
_ssn => undef,
_address => undef
};
bless $self, $class;
return $self;
}
Other object-oriented languages have the concept of security of the data to prevent a programmer from changing an objects data directly and so provide accessor methods to modify object data. Perl does not have private variables but we can still use the concept of accessor methods and ask programmers to not mess with our object innards.
For our Person class we
should provides accessor methods for
our object attributes; name,
address,
title, ssn.
#class Person
package Person;
use strict;
use Address; #Person class will contain an Address
#constructor
sub new {
my ($class) = @_;
my $self = {
_firstName => undef,
_lastName => undef,
_ssn => undef,
_address => undef
};
bless $self, $class;
return $self;
}
#accessor method for Person first name
sub firstName {
my ( $self, $firstName ) = @_;
$self->{_firstName} = $firstName if defined($firstName);
return $self->{_firstName};
}
#accessor method for Person last name
sub lastName {
my ( $self, $lastName ) = @_;
$self->{_lastName} = $lastName if defined($lastName);
return $self->{_lastName};
}
#accessor method for Person address
sub address {
my ( $self, $address ) = @_;
$self->{_address} = $address if defined($address);
return $self->{_address};
}
#accessor method for Person social security number
sub ssn {
my ( $self, $ssn ) = @_;
$self->{_ssn} = $ssn if defined($ssn);
return $self->{_ssn};
}
sub print {
my ($self) = @_;
#print Person info
printf("Name:%s %s\n\n", $self->firstName, $self->lastName );
}
1;
Making babies
Object-oriented programming sometimes
involves inheritance. Inheritance
simply means allowing one class
called the Child to inherit
methods and attributes from another,
called the Parent one so you
don't have to write the same code
again and again. For example, we can
have a class Employee which inherits
from Person. This is an referred to
as an "isa" relationship because an
Employee is a Person. Perl has a
special variable, @ISA, to help with
this. @ISA which governs (method)
inheritance. So to create a new
Employee class that will inherit
methods and attributes from our
Person class we simply code:
# class Employee package Employee; use Person; use strict; our @ISA = qw(Person); # inherits from Person
What we have done is load the Person class and declare that Employee class inherits methods from it. We have declared no methods for Employee but an Employee object will behave just like a Person object. We should be able to write code:
#create Employee class instance
my $khurt = new Employee();
#set object attributes
$khurt->firstName('Khurt');
$khurt->lastName('Williams');
without any other changes.
Now let's add some methods.
# class Employee
package Employee;
use Person;
use strict;
our @ISA = qw(Person); # inherits from Person
#constructor
sub new {
my ($class) = @_;
#call the constructor of the parent class, Person.
my $self = $class->SUPER::new();
$self->{_id} = undef;
$self->{_title} = undef;
bless $self, $class;
return $self;
}
#accessor method for id
sub id {
my ( $self, $id ) = @_;
$self->{_id} = $id if defined($id);
return ( $self->{_id} );
}
#accessor method for title
sub title {
my ( $self, $title ) = @_;
$self->{_title} = $title if defined($title);
return ( $self->{_title} );
}
sub print {
my ($self) = @_;
# we will call the print method of the parent class
$self->SUPER::print;
$self->address->print;
}
1;
Looking at the code you will notice
that we have a new
method and a print
method. Both a Child class and its
Parent class have the same method
defined. We have overridden the
Parent class' methods with the ones
from the Child. When those methods
are called on an Employee object we
will get the Employee class' version
of the method. This concept of using
the methods of and existing object
and modifying them is known as
polymorphism.
Putting it together
So now we have a complete set of classes we can write a small program to test them.
use strict;
use warnings;
use diagnostics;
use Employee;
#create Employee class instance
my $khurt = eval { new Employee(); } or die ($@);
#set object attributes
$khurt->firstName('Khurt');
$khurt->lastName('Williams');
$khurt->id(1001);
$khurt->title('Executive Director');
$khurt->address( new Address() );
$khurt->address->street('10 Anywhere Lane');
$khurt->address->city('Anytown');
$khurt->address->state('NJ');
$khurt->address->zip('12345');
#diplay Employee info
$khurt->print();
Let's execute our code and see the output
$ ./test.pl Name:Khurt Williams Address: 10 Anywhere Lane Anytown, NJ 12345
It works! We covered the basics of object oriented programing in Perl. I hope this article was informative and useful.



