Reputation: 1652
Please see the perldoc for oop http://perldoc.perl.org/perlobj.html
As per the document: "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."
Now, I am in a situation where I need the SUPER to refer to the superclass(es) of the object.
So, looking for any way to achieve it.
Upvotes: 10
Views: 11158
Reputation: 3635
It's fairly rare that you really need to do something like this, usually it's a sign that your mucking about inside an object in a way that will come back to bite you later. If it's really what needs to be done you can change your package just for the method call to change what SUPER sees, or override method look up by calling the full method name.
{
package BaseClass;
sub new { bless \my $self, shift; }
sub foo {
my $self = shift;
print "BaseClass::foo()\n";
}
}
{
package SubClass;
our @ISA = qw(BaseClass);
sub foo {
my $self = shift;
print "SubClass::foo()\n";
$self->SUPER::foo();
}
}
{
package ParentClass;
sub new { bless \my $self, shift; }
sub bar {
my $self = shift;
print "ParentClass::bar()\n";
}
}
{
package ChildClass;
our @ISA = qw(ParentClass);
sub foo {
my $other = SubClass->new();
print "ChildClass::foo()\n";
# fails trying to find ParentClass::foo()
eval { $other->SUPER::foo(); } or warn $@;
# thinks this is SubClass and finds BaseClass::foo()
{ package SubClass; $other->SUPER::foo(); }
# if you know the correct class that SUPER::foo() would have called (but this will also work if it was the wrong class)
$other->BaseClass::foo();
}
sub bar {
my $self = shift;
print "ChildClass::bar()\n";
$self->SUPER::bar();
}
}
my $obj_1 = SubClass->new();
$obj_1->foo();
my $obj_2 = ChildClass->new();
$obj_2->bar();
$obj_2->foo();
A cleaner option is to refactor your methods so that you can access both the base class and sub class methods without trying to subvert the object system.
{
package BaseClass;
sub new { bless \my $self, shift; }
sub foo {
my $self = shift;
print "BaseClass::foo()\n";
}
}
{
package SubClass;
our @ISA = qw(BaseClass);
sub bar {
my $self = shift;
print "SubClass::bar()\n";
$self->SUPER::foo();
}
}
my $obj = SubClass->new();
$obj->foo();
$obj->bar();
Or provide a method to call the base class method.
{
package BaseClass;
sub new { bless \my $self, shift; }
sub foo {
my $self = shift;
print "BaseClass::foo()\n";
}
}
{
package SubClass;
our @ISA = qw(BaseClass);
sub foo {
my $self = shift;
print "SubClass::foo()\n";
$self->SUPER::foo();
}
sub bar {
my $self = shift;
$self->SUPER::foo();
}
}
my $obj = SubClass->new();
$obj->foo();
$obj->bar();
The best answer really depends on what you are really trying to do an why that requires you to work around standard inheritance.
Upvotes: 10
Reputation: 118605
Given a class structure like
package BaseClass;
sub some_method { ... }
...
package SubClass;
our @ISA = qw(BaseClass);
sub some_method { ... }
...
and code like
package MainPackage;
our @ISA = qw(SuperPackage);
my $object = new SubClass(...);
you want to invoke BaseClass::some_method
on the object. Inside the SubClass
package, you could call $object->SUPER::some_method(...)
. But whether or not you are inside the SubClass
package, you can always explicitly call the method you want as
BaseClass::some_method($object, ...)
Upvotes: 3