Subhayan Bhattacharya Subhayan Bhattacharya - 6 months ago 15
Perl Question

Inheritance in Perl

I have two classes, one is the base class(Employee) and the other its subclass which inherits it (Extend) the codes of which are shown below :

package Employee;
require Exporter;
our @EXPORT = ("getattr");

our $private = "This is a class level variable";

sub getattr {
print "Inside the getattr function of Employee.pm module \n";
$self = shift;
$attr = shift;
return ($self->{$attr});
}
1;


================

package Extend;

use base qw(Employee);

sub new {
print "Inside new method of Employee.pm \n";
my $class = shift;
my %data = (
name => shift,
age => shift,
);

bless \%data , $class;
}

sub test {
print "Inside test method of Extend class \n";
}

1;


==================

Now I have another piece of code which is using the Extend class :

use Extend;

my $obj = Extend->new("Subhayan",30);
my $value = $obj->getattr("age");
print ("The value of variable age is : $value \n");
$obj->test();
print "Do i get this : $obj.$private \n";


My question is regarding the variable $private defined in the parent class. As per my concept of inheritance attributes and methods of the parent class should be available through the subclass object . For example the function getattr runs fine . But why am I not being able to access $private variable using the base class Extend object .

What am I missing here ? Can someone please help ?

Answer

Variables don't get inherited the same way subs do. To access it, you need to specify the entire package name (and yes, when you declare $private, you need our, not my):

print "$Employee::private\n";

It's much more robust to define accessor methods:

# Employee package
sub private {
    return $private;
}

...then in your script:

my $var = private();

To inherit object attributes from Employee, you can do:

# Employee

sub new {
    my $self = bless {
        dept => 'HR',
        hours => '9-5',
    }, shift;

    return $self;
}

# Extend

sub new {
    my $class = shift;
    my $self = $class->SUPER::new; # attrs inherited from Employee
    $self->{extended} = 1;
    return $self;
}

# script

my $extend = Extend->new;

Now $extend looks like:

{
    dept => 'HR',
    hours => '9-5',
    extended => 1,
}

You most likely wouldn't set dept or hours in the base class as it will apply to all employees, but I digress.