in reply to Inheritance - calling parent constructor

Assuming you are rolling your own constructor, as opposed to using an existing OO framework like Moose or Mouse, you should not explicitly invoke your parent class. Rather, as described in the Overridden Methods section of perltoot, you should invoke the pseudo class SUPER, as in:

package Child; use base qw(Parent); sub new { my ($class, $arg1, $arg2, $arg3) = @_; #my $self = SUPER->new($arg1, $arg2); my $self = $class->SUPER::new($arg1, $arg2); #$self->{arg3} => $arg3; $self->{arg3} = $arg3; #bless $self, $class; return $self; } return 1;

You do need to explicitly invoke the SUPER class, since you are overriding the local new method, and Perl does not a priori know what you've decided to call your constructor. If you were to just say "new", it would call the constructor recursively.

Regarding your second question, as documented in base, use base 'Parent'; will perform the functions intended by the use Exporter;... code, though not following the explicitly same approaches.

Update: Should have tested before posting. Corrected code above (left original commmented) and fixed an OP typo for argument assignment.

Replies are listed 'Best First'.
Re^2: Inheritance - calling parent constructor
by ikegami (Patriarch) on Dec 29, 2009 at 18:17 UTC

    Wrong syntax. That will attempt to call new in package SUPER. And you forgot to remove the bless that's now useless. See my reply to the OP for the correction.

      Wrong syntax. That will attempt to call new in package SUPER.

      - That's what I thought - i got the correct syntax from the link you had - thanks

      And you forgot to remove the bless that's now useless.

      - Could you elaborate here? I thought I have read that re-blessing is bad and was searching for best practices on re-blessing without much luck.

        I thought I have read that re-blessing is bad

        More accurately, it shouldn't be needed. If it's needed, it's a sign something else is wrong.

Re^2: Inheritance - calling parent constructor
by bob_dobalina (Sexton) on Dec 29, 2009 at 18:42 UTC
    thanks for the info - that works for me. I wonder the difference between using class name and SUPER? Is it OK to not have a constructor in the child object? This seems to work.
      The difference between hard-coding Parent-> as opposed to invoking SUPER is relevant when you have multiple levels of inheritance. If you created a Grandchild, a method using SUPER would climb the @ISA tree to resolve new, whereas hard-coding Parent-> will go straight there. It's also useful for code reuse, since SUPER is not package specific. For example, if you had a series of validation routines, you could open sub validate { with my $self = shift; $self->SUPER::validate(); and it would crawl the inheritance tree correctly without refactoring and the associated fagility.

      You would only need to define a constructor in the child object if it requires additional functionality - in this case, because Child has an additional property.

      If you are interested in all this or rolling your own OO, a read read through of perlboot and perltoot is merited.

      You could use
      my $self = $class->Parent::new(...);
      instead of
      my $self = $class->SUPER::new(...);

      And you might even have to in some weird situations (although use mro 'c3'; would probably be a better fix).

      But using Parent is redundant. You already specified it's the parent class. To use it here is to needlessly hardcode a value. Nothing good can come of that.