adaughterson has asked for the wisdom of the Perl Monks concerning the following question:

Greetings exalted ones:

I feel like I'm missing something really obvious here, but when I try to move my custom sort method into the base class, $a and $b don't magically appear like when the sort method is contained within the current context, or inline.

Is it even possible to use an inherited method for my custom sort? Thanks, Adam

Replies are listed 'Best First'.
Re: Inherit custom sort method from base class
by vsespb (Chaplain) on Oct 01, 2013 at 22:01 UTC
    Sort comparison function should be a.. function, not a method.

    Thus I don't quite understand how class inheritance applies here.

    Would you mind simplifying your code to proof-of-concept example and posting here so we would see the problem?

      I can certainly do that.

      The base-class:
      Package MyBaseClass; sub new { my $class = shift; my $self = {}; bless($self,$class); $self->_init(); return $self; } sub _init { my $self = shift; @{$self->{things}} = qw(thing_0.1 thing_0.2 thing_0.3 thing_11.0 thi +ng_11.1); # etc,etc return $self; } # $a and $b don't seem to exist within this context sub specialSort { my $self = shift; my @aParts = split(/[_.]/, $a); my @bParts = split(/[_.]/, $b); return 1 if (int $a_parts[1] > int $b_parts[1] || ($a_parts[1] eq $b +_parts[1] && (int $a_parts[2]) > (int $b_parts[2]))); return -1 if (int $a_parts[1] < int $b_parts[1] || ($a_parts[1] eq $ +b_parts[1] && (int $a_parts[2]) < (int $b_parts[2]))); return 0 if ($a eq $b); die((caller(0))[3] . " LOGIC error."); } 1;
      The subclass:
      package MySubclass; require MyBaseClass; our @ISA = qw(MyBaseClass); sub new { my $class = shift; my $self = {}; bless($self,$class); $self->_init(); return $self; } sub _init { my $self = shift; MyBaseClass::_init($self); return $self; } sub doSomething { my $self = shift; # this works foreach my $thing(sort specialSort @{$self->{things}}) { # do something with $thing... } # this doesn't work foreach my $thing(sort $self->specialSort @{$self->{things}}) { # do something with $thing... } } sub specialSort { # Notice that there is no 'my $self = shift' here... my @aParts = split(/[_.]/, $a); my @bParts = split(/[_.]/, $b); return 1 if (int $a_parts[1] > int $b_parts[1] || ($a_parts[1] eq $b +_parts[1] && (int $a_parts[2]) > (int $b_parts[2]))); return -1 if (int $a_parts[1] < int $b_parts[1] || ($a_parts[1] eq $ +b_parts[1] && (int $a_parts[2]) < (int $b_parts[2]))); return 0 if ($a eq $b); die((caller(0))[3] . " LOGIC error."); } 1;
        Try
        sort { $self->specialSort($a, $b) } @{$self->{things}})
        and remove specialSort from MySubclass.
        you have to use 1st and 2nd arguments instead of $a and $b in base class' specialSort

        You cannot use $self->specialSort as subroutine name, so you have to use new "subroutine":
        { $self->specialSort($a, $b) }

        Also, technically, you can put
        use base qw/Exporter/; @EXPORT = qw/specialSort/;

        into base class,
        then remove specialSort from MySubclass, and then it will work.
        but it's probably bad style to mix inheritance and exported functions.

        UPD: fixed $a,$b in code