Click here to Skip to main content
15,867,686 members
Articles / Programming Languages / Perl

Perl Object Oriented Programming

Rate me:
Please Sign up or sign in to vote.
4.49/5 (37 votes)
12 Nov 2002CPOL5 min read 514.7K   1.8K   38   56
The basics of Object Oriented Programming in Perl
This article provides a brief introduction to object-oriented programming (OOP) in Perl. It explains the concepts of objects, classes, and methods. It demonstrates how to create a class, define methods, create objects, and use accessor methods. It also discusses inheritance and polymorphism in Perl's OOP. Finally, it provides a small program as an example to test the implemented classes.

Camel POOP

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 three simple rules as put forth by Larry Wall in Object Oriented Perl.

Object-oriented programmers are familiar with the concept of objects and classes, but I will review that here quickly. An object is a thing that provides access to or modification of data. A class describes the attributes of a particular kind of object and how those objects can be accessed and modified. A method is how 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 a 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 include 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 reused repeatedly. 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:

PERL
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 how 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:

PERL
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 a Person object, we use the Perl "arrow" notation. If the variable $khurt contains a Person object, we would call print on that object by writing:

PERL
$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 is to operate.

How do we create the invoking object?

Bless Me, Father,

We need an object constructor to create an instance of a class (an object). 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 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;

PERL
#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 takes 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:

PERL
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.

PERL
#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 data security to prevent a programmer from changing an object data directly and provide accessor methods to modify object data. Perl does not have private variables, but we can still use accessor methods and ask programmers not to mess with our object innards.

We should provide accessor methods for our Person class for our object attributes; name, address, title, and SSN.

PERL
#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 means allowing one class, called the Child, to inherit methods and attributes from another, called the Parent, so you don't have to write the same code repeatedly. For example, we can have a class Employee which inherits from Person. This is called an "isa" relationship because an employee is a person. Perl has a special variable, @ISA, to help with this. @ISA governs (method) inheritance. So to create a new Employee class that will inherit methods and attributes from our Person class, we code:

PERL
# class Employee
package Employee;
use Person;
use strict;
our @ISA = qw(Person);    # inherits from Person

We have loaded the Person class and declared 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:

PERL
#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.

PERL
# 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 the 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 an existing object and modifying them is known as polymorphism.

Putting It Together

So now that we have a complete set of classes, we can write a small program to test them.

PERL
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');

#display 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 programming in Perl, and I hope this article was informative and useful.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
United States United States
Khürt Williams is an independent information systems security consultant working for private industry and government in the Princeton area. He holds CISSP, CCSP and ITIL certifications.

Comments and Discussions

 
Questiononly one person Pin
Mark Hutchinson Nov202122-Dec-21 14:35
Mark Hutchinson Nov202122-Dec-21 14:35 
Questionse and ur usage? Pin
Member 1276301527-Sep-16 11:55
Member 1276301527-Sep-16 11:55 
GeneralMy vote of 5 Pin
tusharvaja21-Aug-13 3:02
tusharvaja21-Aug-13 3:02 
QuestionThank You Pin
Member 1015217511-Jul-13 20:21
Member 1015217511-Jul-13 20:21 
QuestionVery Very GOOOOOOD ;thanks Pin
Member 1004217210-May-13 0:04
Member 1004217210-May-13 0:04 
QuestionError when running Pin
Member 963090825-Nov-12 23:30
Member 963090825-Nov-12 23:30 
when I tried to implement on my computer. It shows the following error messages.

"Can't call method "street" on an undefined value at test.pl line 18 (#1)
(F) You used the syntax of a method call, but the slot filled by the
object reference or package name contains an undefined value. Something
like this will reproduce the error:

$BADREF = undef;
process $BADREF 1,2,3;
$BADREF->process(1,2,3);

Uncaught exception from user code:
Can't call method "street" on an undefined value at test.pl line 18.
at test.pl line 18"

Seems there is something wrong at line 16
"$khurt->address(new Address());'"

is the syntax error or something else?
QuestionPass initialization data to constructor? And multiple constructors? Pin
daluu12-Mar-11 19:38
daluu12-Mar-11 19:38 
GeneralLove You!! Pin
xuqiqi19-Oct-10 1:56
xuqiqi19-Oct-10 1:56 
GeneralLost you Pin
Inktpatronen11-Jun-10 12:26
Inktpatronen11-Jun-10 12:26 
QuestionWhy is $self declared in the accessor methods? Pin
JasonBL22-Oct-09 4:05
JasonBL22-Oct-09 4:05 
Generalneed a code for this project Pin
kishore01617-Apr-09 19:38
kishore01617-Apr-09 19:38 
QuestionReusing the text in this article Pin
Reswaran22-Apr-08 4:07
Reswaran22-Apr-08 4:07 
GeneralRead-Only Accessor Pin
Daaron7-Apr-08 17:12
Daaron7-Apr-08 17:12 
QuestionWhy do we need 1;? Pin
Reswaran16-Nov-07 2:24
Reswaran16-Nov-07 2:24 
AnswerRe: Why do we need 1;? Pin
GauranG Shah9-Dec-07 21:41
GauranG Shah9-Dec-07 21:41 
GeneralRe: Why do we need 1;? Pin
Reswaran1-Jan-08 21:37
Reswaran1-Jan-08 21:37 
Questionwhat is difference in pakage and module Pin
sanjaymaned11-Jun-07 19:46
sanjaymaned11-Jun-07 19:46 
AnswerRe: what is difference in pakage and module Pin
atanation2-Jun-08 1:25
atanation2-Jun-08 1:25 
Generalbless behavior Pin
sanjaymaned6-Jun-07 20:11
sanjaymaned6-Jun-07 20:11 
GeneralRe: bless behavior Pin
Khürt Williams7-Jun-07 0:58
professionalKhürt Williams7-Jun-07 0:58 
Questionwhat is difference in use and require ? Pin
sanjaymaned5-Jun-07 23:00
sanjaymaned5-Jun-07 23:00 
AnswerRe: what is difference in use and require ? Pin
Khürt Williams6-Jun-07 15:48
professionalKhürt Williams6-Jun-07 15:48 
GeneralRe: what is difference in use and require ? Pin
sanjaymaned6-Jun-07 20:09
sanjaymaned6-Jun-07 20:09 
Questionwhat is difference in functions of s/// and tr/// ? Pin
sanjaymaned5-Jun-07 21:40
sanjaymaned5-Jun-07 21:40 
AnswerRe: what is difference in functions of s/// and tr/// ? Pin
Khürt Williams6-Jun-07 15:54
professionalKhürt Williams6-Jun-07 15:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.