Skip to page content or Skip to Accesskey List.

Work

Main Page Content

Camel Poop Object Oriented Programming In Perl

Rated 4.12 (Ratings: 7)

Want more?

  • More articles in Code
 
Picture of khurtwilliams

Khurt Williams

Member info

User since: 19 Dec 2002

Articles written: 1

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

", $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

", $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.

Khurt Williams is a IT security professional at a pharmaceutical company in the Central New Jersey area. He maintains a blog at http://islandinthenet.com/. View my profile on LinkedIn

The access keys for this page are: ALT (Control on a Mac) plus:

evolt.org Evolt.org is an all-volunteer resource for web developers made up of a discussion list, a browser archive, and member-submitted articles. This article is the property of its author, please do not redistribute or use elsewhere without checking with the author.