带有 Moo 的 Perl:如何调用超类的方法实现?
Perl with Moo: How to call superclass's implementation of a method?
我有一个 class X
和一个子 class Y
。 X
有一个方法 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)
如何使用 Moo
模块在 Perl 中执行此操作?
这可以通过 SUPER::
pseudo-class 在 Perl 中完成,它是 Perl 方法解析系统的一部分。你只要把它放在 method-call 前面就行了。它不适用于 class 方法或函数调用。
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;
如果您有 multi-level 继承,您甚至可以使用它来调用每个 parent 的方法。
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
。
正如 docs 指出的那样:
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";
我有一个 class X
和一个子 class Y
。 X
有一个方法 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)
如何使用 Moo
模块在 Perl 中执行此操作?
这可以通过 SUPER::
pseudo-class 在 Perl 中完成,它是 Perl 方法解析系统的一部分。你只要把它放在 method-call 前面就行了。它不适用于 class 方法或函数调用。
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;
如果您有 multi-level 继承,您甚至可以使用它来调用每个 parent 的方法。
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
。
正如 docs 指出的那样:
No support for
super
,override
,inner
, oraugment
- the author considers augment to be a bad idea, andoverride
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";