I have two classes: a base class, Foo::Base and a derived class, Foo::Base::Sub
. I want to have Foo::Base::Sub
do some type and data checking on the constructor`s argument--a hash--before blessing it. I've tried overriding Foo::Base->new
's constructor, doing the checks and then calling Foo::Base->new
(since the code would be exactly the same):
package Foo::Base::Sub;
sub new {
...check argument's type and data...
Foo::Base->new(%my_hash)
}
The problem is that by calling Foo::Base
's constructor, the hash will now be blessed as a Foo::Base object and not a Foo::Base::Sub object. The obvious solution is simply to put the code from Foo::Base::new
into Foo::Base::Sub::new
but then I'm repeating code. The other thing is that Foo::Base is not mine--thus I'd like to avoid having to modify it after the module has loaded or forking it unnecessarily.
It seems to me that this problem must have come up before and so there must be a canonical solution. Moreover, it really touches on type coercion which is generally not an issue Perl.
So is there a simple modification or am I going about this the wrong way?
A standard Perl idiom is to use SUPER
to call up the inheritance chain:
@Foo::Base::Sub::ISA = qw(Foo::Base);
sub new {
my $package = shift;
my $self = $package->SUPER::new();
# Other subconstructor stuff here
return $self;
}
As noted in the comments, Foo::Base
's constructor must use the two-argument form of bless
:
sub new {
my $package = shift;
my $self = bless {}, $package;
# Other superconstructor stuff here
return $self;
}
When the superclass' constructor is called, $package
will be the subclass.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With