nomis80 has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

This must be a trivial question but I couldn't find any answer for it in the archives or by using Google. Here goes...

I want to inherit from a class, and I want my child class' constructor to add some behavior to the parent's. I didn't code the parent class and am not in a position to modify it, which means I can't do the _init() trick.

package Parent; sub new { my $invocant = shift; my $class = ref($invocant) || $invocant; my $self = {}; bless $self, $class; return $self; } package Child; use base qw(Parent); sub new { # what goes here? $self->do_child_specific_stuff(); return $self; }

What code should go into Child::new()? Thanks!

Replies are listed 'Best First'.
Re: Overriding constructor
by Joost (Canon) on Aug 12, 2005 at 15:07 UTC
    In this case, it's probably best to do
    package Child; use base qw(Parent); sub new { my $class = shift; my $self = $class->SUPER::new(); # call superclass' constructor wi +th provided classname $self->do_child_specific_stuff(); return $self; }

    If the superclass doesn't do the right thing with the provided class (your provided code does the right thing, but you never know..) you can force the right class after the fact:

    # ... my $self = $class->SUPER::new(); bless $self,$class; # re-bless to right classname $self->do_child_specific_stuff(); # ...
Re: Overriding constructor
by phaylon (Curate) on Aug 12, 2005 at 14:55 UTC
    perldoc perlobj (Go for SUPER::) and NEXT maybe a topic for you.

    Ordinary morality is for ordinary people. -- Aleister Crowley
      Uh, yeah, I knew about SUPER. But to call a method of Parent, I'd have to call it on an instance of Child, which I don't have yet because that's what I'm trying to create. Please explain.

        You only need an invocant, not a blessed invocant. You can call SUPER on $class.

        Then NEXT would be my choice to go. I haven't used SUPER a long time, so my apologies if it didn't fit.

        Ordinary morality is for ordinary people. -- Aleister Crowley
Re: Overriding constructor
by merlyn (Sage) on Aug 12, 2005 at 15:38 UTC

      It's cleaned up in parts, but still scattered about in perlobj, and the way bottom part of perlmodlib, though at least those present it as an option, not as dogma. perltooc gets into it, too, but at least there's broader context about calling things as class methods versus object methods.

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: Overriding constructor
by Codon (Friar) on Aug 12, 2005 at 15:31 UTC

    You want your new() method to be very simple. It basically blesses the object, then calls $self->init() which does all the real work. You parent class may have this as an abstract method (just dies; forces child to define sub init) or it could be an empty method that just returns.

    All derived classes would inherit the Parent new() method and either define or inheirit init().

    package Parent; sub new { my $invocant = shift; my $class = ref($invocant) || $invocant; my $self = {}; bless $self, $class; $self->init(@_); return $self; } sub init { return; # or die to force child class to do something here } package Child; use base qw(Parent); sub init { # do child specific stuff; }
    For a great OOP reference, see Damian's book Object Oriented Perl.

    Ivan Heffner
    Sr. Software Engineer, DAS Lead
    WhitePages.com, Inc.