I'm trying to create the abstract method pattern using Perl and Moose. What I don't understand is that if I override a method from the AbstractClass it will eventually be called anyway. Why is this and is there a way to avoid the superclass from being called?
Main
package main;
use AbstractSort;
use OrderedSort;
# Sub class test
my $ordered = OrderedSort->new(array => [1, -1, 23, 34123, -24324]);
$ordered->sortData();
AbstractClass
package AbstractSort;
use namespace::autoclean; # Trims EXPORTER
use Moose;
has 'array' => (traits => ['Array'],
is => 'ro',
isa => 'ArrayRef[Int]',
default => sub { [] },
handles => {
get_array => 'get',
count_array => 'count',
});
sub sortData{
my $self = shift;
print "Sorting data..\n";
_sortAlgorithm($self->array);
# ...
}
# Protected method here is the actual algorithm
sub _sortAlgorithm {
die 'You must override _sortAlgorithm() in a subclass';
# but Moose will always call the superclass which then makes it die
}
SubClass
package OrderedSort;
use namespace::autoclean; # Trims EXPORTER
use Moose;
extends 'AbstractSort';
# Override and mmpl _sortAlgorithm
override _sortAlgorithm => sub {
my $self = shift;
# ....
};
before '_sortAlgorithm' => sub {
my $self = shift;
# ...
return;
};
You are calling _sortAlgorithm
as a function in the same package in AbstractSort`, and not as a method.
sub sortData {
my $self = shift;
# there is something missing here!
_sortAlgorithm( $self->array );
}
That way, it will always be called in the same package, because it's not an OOP method call.
You need to do $self->_sortAlgorithm
instead.
sub sortData {
my $self = shift;
print "Sorting data..\n";
$self->_sortAlgorithm( $self->array );
# ...
}
It will now not die
any more, because it looks up the _sortAlgorithm
method on $self
, which is an instance of your subclass.
The fact that you actually have my $self = shift
on your overridden method could have given that away, as you were also not passing $self
into it.
You should also not be passing around $self->array
. The algorithm method also has access to $self->array
, so if you want to sort the data that is attached to your object, just use it directly in there.
Also note that typical naming conventions in Perl suggest snake_case method and variable names, and CamelCase package names.