invoking superclass constructors

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

perldoc perlobj documents the user of SUPER as

    As a special case of the above, you may use the "SUPER"
    pseudo-class to tell Perl to start looking for the method in the
    packages named in the current class's @ISA list.


    It is important to note that "SUPER" refers to the
    superclass(es) of the current package and not to the
    superclass(es) of the object. Also, the "SUPER" pseudo-class can
    only currently be used as a modifier to a method name, but not
    in any of the other ways that class names are normally used, eg:

           something->SUPER::method(...);      # OK

For some years, I've been invoking superclass constructors[*]
like this:

sub new
    my ($class, $arg) = @_;
    my $self;

    $self = Super::Class->new('Hmpf', $arg);
    return bless($self, $class);

The most striking problem with this is that this will only work when the
superclass constructor doesn't call any possibly overloaded methods
after creating the instance (via bless). I didn't really need this so
far until today (because of an class representing a HTTP-request which
invokes an overloaded method add_default_headers where subclasses both
need to add their own default headers and provide 'implied arguments' to
the superclass ctor). At this point, I remembered the

    It is important to note that "SUPER" refers to the
    superclass(es) of the current package and not to the
    superclass(es) of the object.

I've been reading over for years without ever understanding why it was
written: In the context of the given problem, it means that it is
possible to use the class argument passed to the subclass constructor as
invocant for the superclass one as the search for a method will start in
the packages named in @ISA regardless of the actual invocant. Ie, this

sub new
    return $_[0]->SUPER::new($_[1], RESOURCE);

will invoke the superclass constructor with the current class argument
as class argument and the additional argument provided by the subclass
constructor. That will then bless the object into the correct class and
invoke any overloaded methods as it should.

[*] A constructor is supposed to create a fully initialized object
    instance, ie it's not just the

sub new
    return bless({}, $_[0]); # why this again ?!?

of a sequence of (Javay) code looking like this:

my $obj = Class->new(); # [**]


That's something which isn't supposed to occur at all as this
'encapsulation' things means 'only the class has knowledge about and
direct access to the object representation' and that's obviously no
longer the case when the representation is 1:1 mirrored by the public

[**] Boldly avoiding the lip service altogether

my $obj = bless({}, 'Class');

works, too.

Site Timeline