Hi Team Daniweb,

Explain perlOOP concepts (basics and a bit advanced) with simple examples to understand what is OOP and how can we use this concepts in PERL.

Thanks!

Anil A Kumar

Hi,
First of, there is nothing like PERL,because perl is not an acronym. The language is Perl ( with capital letter ) and the interpreter is called perl ( with small letter ). What's the difference between "perl" and "Perl"?

That been said OOP in perl is a whole book, so it will be difficult to fully expalin that here. However, in contrary to the view of those who program in other OOP languages, programs in perl can also be implimented in OOP.

So, to understand OOP in Perl, first you need to understand what references are in Perl. Please see perlref.

Why is that?

  1. An object is simply a reference that happens to know which class it belongs to.
  2. A class is simply a package that happens to provide methods to deal with object references.
  3. A method is simply a subroutine that expects an object reference (or a package name, for class methods) as the first argument.

For the full discuss of these please check perlobj.

SIMPLE EXAMPLES

There are no special class syntax in Perl. Classes in Perl are modules, when and where subroutines are used as methods , which are written as package Module::Name see Perl Classes.

See below

package Animal;
use warnings;
use strict;

sub new {
    my $type  = shift;
    my $class = ref($type) || $type;
    my $self  = {
        'name'  => shift,
        'age'   => shift,
        'speak' => shift,
    };
    return bless $self, $class;
}

sub name {
    my $self = shift;
    $self->{'name'} = shift if (@_);
    return $self->{'name'};
}

sub age {
    my $self = shift;
    $self->{'age'} = shift if (@_);
    return $self->{'age'};
}

sub speak {
    my $self = shift;
    $self->{'speak'} = shift if (@_);
    return $self->{'speak'};
}

sub print_out {
    my $self = shift;
    print "\nMy name is: ", $self->name(),
      ", \nI am ", $self->age(),
      " Old, \nI say ", $self->speak, $/;
}

1;   # always return true

The above is saved as Animal.pm not '.pl'

To implement then, you can write a '.pl' script like so:

#!/usr/bin/perl
use warnings;
use strict;

use Animal;

my $cat = Animal->new( 'Pussy', 3, 'mewo' );
$cat->print_out();

my $cat2 = Animal->new( '', '', 'mewo too' );
$cat2->name('Tom');
$cat2->age(4);
$cat2->print_out();

Please note, that new subroutine is not special in Perl. It can as well be given another name altogehter.

Let write another class called Dragon to inherite from class Animal.

package Dragon;
use warnings;
use strict;

use base qw(Animal);

sub dragon {
    my $type  = shift;
    my $class = ref($type) || $type;
    my $self  = $class->SUPER::new();
    $self->{'Ability'} = shift;
    return bless $self, $class;
}

sub ability {
    my $self = shift;
    $self->{Ability} //= shift;
    return $self->{'Ability'};
}

sub print_out {
    my $self = shift;
    $self->SUPER::print_out();
    print "I can ", $self->ability, "\n";
}

1;

then implement like so:

#!/usr/bin/perl
use warnings;
use strict;

use Dragon;

my $cat3 = Dragon->dragon();  # new was not used

$cat3->name('dracular');
$cat3->age(1_000_000);
$cat3->speak('fire-balls');
$cat3->ability('fly');

$cat3->print_out();  # still works

All that is classic OOP in Perl. In the recent and moderm Perl, new Object System has been written for Perl 5, which takes all the boiler plate away. You will only focus on what you really have to.

Let re-implement all we did in classic OOP perl above, using Moose.

#!/usr/bin/perl
use warnings;
use strict;

{

    package Animal;
    use Moose;

    has 'name' => (
        is  => 'rw',
        isa => 'Str',
    );

    has 'age' => (
        is  => 'rw',
        isa => 'Int',
    );

    has 'speak' => (
        is  => 'rw',
        isa => 'Str',
    );

    sub print_out {
        my $self = shift;
        print "\nMy name is: ", $self->name(),
          ", \nI am ", $self->age(),
          " Old, \nI say ", $self->speak, $/;
    }

  no Moose;
  __PACKAGE__->meta->make_immutable;

}

my $cat = Animal->new( name => 'pussy', age => 3, speak => 'mewo' );
$cat->print_out();

my $cat2 = Animal->new( speak => 'mewo too' );
$cat2->name('tom');
$cat2->age(4);
$cat2->print_out();

{

    package Dragon;
    use Moose;

    extends 'Animal';

    has 'ability' => (
        is      => 'rw',
        isa     => 'Str',
        default => 'fly',
    );

    sub print_out {
        my $self = shift;
        $self->SUPER::print_out();
        print $self->ability;
    }
  no Moose;
  __PACKAGE__->meta->make_immutable;
}

my $cat3 = Dragon->new();

$cat3->name('dracular');
$cat3->age(1_000_000);
$cat3->speak('fire-balls');
$cat3->ability('I can fly');
$cat3->print_out();

Code implemented in Moose is very clean, and all you have to do is just get focus on your work. Moose has other siblings, namely Mouse and Moo.

This article has been dead for over six months. Start a new discussion instead.