【问题标题】:Perl with Moo: How to call superclass's implementation of a method?Perl with Moo:如何调用超类的方法实现?
【发布时间】:2017-06-13 21:20:53
【问题描述】:

我有一个类 X 和一个子类 YX 有一个方法 calculate(),我想用一些额外的行为在 Y 中覆盖它,一个 if 语句,如果它失败,调用 X.calculate()。在 Python 中,这将通过以下方式完成:

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)

如何在 Perl 中使用 Moo 模块做到这一点?

【问题讨论】:

    标签: perl oop moo


    【解决方案1】:

    正如docs 指出的那样:

    不支持superoverrideinneraugment - 作者认为扩充是一个坏主意,override 可以翻译

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

    (强调我的)

    #!/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";
    

    【讨论】:

    • 是的!谢谢,这正是我需要的!文档对此非常糟糕。我以为我需要使用before,但即便如此我也不知道该怎么做!再次感谢您的帮助。完美。
    【解决方案2】:

    这可以通过SUPER:: pseudo-class 在 Perl 中完成,它是 Perl 方法解析系统的一部分。您只需将它放在方法调用的前面。它不适用于类方法或函数调用。

    use strict;
    use warnings;
    use feature 'say';
    
    package Foo;
    use Moo;
    
    sub frobnicate {
        my $self = shift;
        say "foo";
    }
    
    package Bar;
    use Moo;
    extends 'Foo';
    
    sub frobnicate {
        my $self = shift;
        say "bar";
        $self->SUPER::frobnicate;    
    }
    
    package main;
    Bar->new->frobnicate;
    

    如果您有多级继承,您甚至可以使用它来调用每个父级的方法。

    package Grandparent;
    sub foo { ... }
    
    package Parent;
    use parent 'Grandparent';
    sub foo { $_[0]->SUPER::foo }
    
    package Child;
    use parent 'Parent';
    sub foo { $_[0]->SUPER::foo }
    

    这将随后在 Child、Parent 和 Grandparent 中调用 foo

    【讨论】:

    • Re "Moo 和 Moose 都支持这个",它是 Perl 方法调度的一部分,所以它总是可用的。
    • 感谢您的帮助。不幸的是,这对我不起作用,我不完全确定为什么......
    猜你喜欢
    • 1970-01-01
    • 2019-01-05
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-16
    相关资源
    最近更新 更多