perloopmoo

Perl with Moo: How to call superclass's implementation of a method?


I have a class X with a subclass Y. X has a method calculate() that I'd like to override in Y with some additional behaviour, an if statement that, if it fails, call X.calculate(). In Python this would be accomplished with:

class X(object):
    def calculate(self, my_arg):
        return "Hello!"

class Y(X):
    def calculate(self, my_arg):
        if type(my_arg) is int and my_arg > 5:
            return "Goodbye!"
        return super(Y, self).calculate(my_arg)

How can I do this in Perl using the Moo module?


Solution

  • As the docs point out:

    No support for super, override, inner, or augment - the author considers augment to be a bad idea, and override can be translated:

    around foo => sub {
      my ($orig, $self) = (shift, shift);
      ...
      $self->$orig(@_);
      ...
    };
    

    (emphasis mine)

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    package X;
    
    use Moo;
    
    sub calculate {
        return 'Hello!'
    }
    
    
    package Y;
    
    use Moo;
    
    extends 'X';
    
    around calculate => sub {
        my $orig = shift;
        my $self = shift;
    
        if ( $_[0] > 5 ) {
            return $self->$orig(@_);
        }
    
        return 'Goodbye!';
    };
    
    package main;
    
    my $y = Y->new;
    
    print $y->calculate(3), "\n";
    print $y->calculate(11), "\n";