如何覆盖Moose :: Role中的sub?

时间:2013-09-23 12:40:48

标签: perl moose

我正在尝试实现一个Moose :: Role类,其行为类似于Java中的抽象类。我想在Role中实现一些方法,但是能够在具体类中覆盖这些方法。如果我使用与扩展类时相同的样式尝试此操作,则会收到错误Cannot add an override method if a local method is already present。这是一个例子:

我的抽象类:

package AbstractClass;

use Moose::Role;

sub my_ac_sub {

    my $self = shift;

    print "In AbstractClass!\n";
    return;
}

1;

我的具体课程:

package Class;

use Moose;

with 'AbstractClass';

override 'my_ac_sub' => sub {

    my $self = shift;

    super;
    print "In Class!\n";
    return;
};

__PACKAGE__->meta->make_immutable;
1;

然后:

use Class;

my $class = Class->new;
$class->my_ac_sub;

我做错了吗?我想要完成的是应该以不同的方式完成的吗?是不是我不想做的事情?

2 个答案:

答案 0 :(得分:4)

原来我错误地使用了它。我打开a ticket并显示了正确的方法:

package Class;

use Moose;

with 'AbstractClass';

around 'my_ac_sub' => sub {

    my $next = shift;
    my $self = shift;

    $self->$next();
    print "In Class!\n";
    return;
};

__PACKAGE__->meta->make_immutable;
1;

进行此更改会产生预期的效果。

答案 1 :(得分:2)

Some time ago,我通过一个仅由requires语句组成的角色来做到这一点。这形成了抽象基类。然后,您可以将默认实现放在另一个类中并继承自:

#!/usr/bin/env perl

use 5.014;

package AbstractClass;

use Moose::Role;

requires 'my_virtual_method_this';
requires 'my_virtual_method_that';

package DefaultImpl;

use Moose;
with 'AbstractClass';

sub my_virtual_method_this {
    say 'this';
}

sub my_virtual_method_that {
    say 'that'
}

package MyImpl;

use Moose;
extends 'DefaultImpl';
with 'AbstractClass';

override my_virtual_method_that => sub {
    super;
    say '... and the other';
};

package main;

my $x = MyImpl->new;

$x->my_virtual_method_this;
$x->my_virtual_method_that;

如果您只想为角色中定义的几种方法提供默认实施,请从requires移除DefaultImpl

输出:

$ ./zpx.pl
this
that
... and the other