Esteemed monks,

I have an OO Perl question ... well 2 actually!

My first question concerns inheritance, specifically @ISA. The code provided, works when package Employee.pm inherits from package Person.pm via:

use base qw( Person );

However when I change this to:

our @ISA = qw( Person );

I get the following error:

Can't locate object method "new" via package "Employee" at person.pl line 7.

I am not quite sure I understand why this happens and would like an explanation. If the class Person.pm can only be inherited by "use base" then that partially defeats the purpose of the encapsulation provided by inside-out classes (as it can't be inherited by saying "our @ISA = qw( Class )").

My next question concerns destruction. I'm aware that Perl calls the sub DESTROY at the end of an objects life. In the example code the Employee::DESTROY method needs to call the SUPER::DESTROY method to take care of the cleaning up required there. I noted that this does not appear to happen otherwise.

That is, when I call SUPER::DESTROY I get the output:

Hi! My name is Nelo and my job is none of your business! Destroying Employee=SCALAR(0x188f4c4) Deleted job ... Destroying Employee=SCALAR(0x188f4c4) Deleted name ... Hi! My name is Amelie and my job is none of your business! Destroying Employee=SCALAR(0x22606c) Deleted job ... Destroying Employee=SCALAR(0x22606c) Deleted name ... Hi! My name is Wole and my job is none of your business! Destroying Employee=SCALAR(0x183296c) Deleted job ... Destroying Employee=SCALAR(0x183296c) Deleted name ... Hi! My name is Hacer and my job is none of your business! Destroying Employee=SCALAR(0x188f4c4) Deleted job ... Destroying Employee=SCALAR(0x188f4c4) Deleted name ...
And when I don't I get:

Hi! My name is Nelo and my job is none of your business! Destroying Employee=SCALAR(0x188f4c4) Deleted job ... Hi! My name is Amelie and my job is none of your business! Destroying Employee=SCALAR(0x22606c) Deleted job ... Hi! My name is Wole and my job is none of your business! Destroying Employee=SCALAR(0x183296c) Deleted job ... Hi! My name is Hacer and my job is none of your business! Destroying Employee=SCALAR(0x188f4c4) Deleted job ...
My question here is "is my assumption correct" and do I need to explicitly call the SUPER::DESTROY in my child class or does Perl really get rid of the attributes defined in the parent class?

Here is the code in full with comments denoting the lines concerned:

#!/usr/bin/perl -w use strict; package main; { for my $name ( qw( nelo amelie wole hacer ) ) { my $person = Employee->new(name=>$name, job=>"none of your bus +iness!"); print "\n", 'Hi! My name is ', ucfirst $person->get_name, ' a +nd my job is ', $person->get_job, "\n"; } } 1; package Person; { use Carp qw( &carp &croak ); use Scalar::Util qw( &refaddr ); # object's attributes my (%name_of); # construct a new object sub new { my ($class, %args) = @_; ref $class and croak "Incorrect Usage: $class->new(%args)"; my $self = bless \do{my $scalar}, $class; $self->_init(%args); return $self; } # initialise the new object's attributes sub _init { my ($self, %args) = @_; ref $self or croak "Incorrect Usage: $self->_init(%args)"; # set values with reasonable defaults $self->set_name( $args{name} || 'unknown' ); } # object accessor methods sub set_name { my ($self, $name) = @_; ref $self or croak "Incorrect Usage: $self->set_name"; $name or croak "No argument provided to set_name"; $name_of{refaddr $self} = $name; } sub get_name { my ($self) = @_; ref $self or croak "Incorrect Usage: $self->get_name"; @_ == 1 or carp "No arguments required by get_name"; return $name_of{refaddr $self}; } # class accessor methods # private (internal) methods # utility (external) methods # destroy the object sub DESTROY { my ($self) = @_; print "Destroying $self\n"; delete $name_of{refaddr $self} and print "Deleted name ...\n"; } } 1; package Employee; { use Carp qw( &carp &croak ); use Scalar::Util qw( &refaddr ); # inherits from ... use base qw( Person ); # works with this :) #~ our @ISA = qw( Person ); # breaks with this :( # object's attributes my (%job_of); # construct new object (inherited) # initialise the new object's attributes sub _init { my ($self, %args) = @_; ref $self or croak "Incorrect Usage: $self->_init(%args)"; # set values with reasonable defaults $self->set_job( $args{job} || 'unknown' ); # initialise the parent class attributes $self->SUPER::_init(%args); } # object accessor methods sub set_job { my ($self, $job) = @_; ref $self or croak "Incorrect Usage: $self->set_job"; $job or croak "No argument provided to set_job"; $job_of{refaddr $self} = $job; } sub get_job { my ($self) = @_; ref $self or croak "Incorrect Usage: $self->get_job"; @_ == 1 or carp "No arguments required by get_job"; return $job_of{refaddr $self}; } # class accessor methods # private (internal) methods # utility (external) methods # destroy the object sub DESTROY { my ($self) = @_; print "Destroying $self\n"; delete $job_of{refaddr $self} and print "Deleted job ...\n"; # call parent destructor $self->SUPER::DESTROY; # comment out and "name" hangs aroun +d ... i think :) } } 1;

Any help is appreciated :)

In reply to inside-out class and "our @ISA" by j1n3l0

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.