Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 如何覆盖Moose::角色中的sub?_Perl_Moose - Fatal编程技术网

Perl 如何覆盖Moose::角色中的sub?

Perl 如何覆盖Moose::角色中的sub?,perl,moose,Perl,Moose,我试图实现一个Moose::Role类,其行为类似于Java中的抽象类。我希望在角色中实现一些方法,但是能够在具体类中重写这些方法。如果使用扩展类时使用的相同样式尝试此操作,则会出现错误如果本地方法已存在,则无法添加覆盖方法。下面是一个例子: 我的抽象类: package AbstractClass; use Moose::Role; sub my_ac_sub { my $self = shift; print "In AbstractClass!\n"; re

我试图实现一个Moose::Role类,其行为类似于Java中的抽象类。我希望在角色中实现一些方法,但是能够在具体类中重写这些方法。如果使用扩展类时使用的相同样式尝试此操作,则会出现错误
如果本地方法已存在,则无法添加覆盖方法。下面是一个例子:

我的抽象类:

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;
我做错什么了吗?我想要完成的事情应该以不同的方式完成吗?我想做的事情根本就不应该做吗?

,我这样做是因为我的角色完全由
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;
如果只想为角色中定义的几个方法提供默认实现,请从
DefaultImpl
中删除
requires

输出:

$ ./zpx.pl this that ... and the other 美元/zpx.pl 这 那个
... 另一个结果是我用错了。我打开并看到了正确的操作方法:

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;

进行此更改具有所需的效果。

使用抽象类对抽象类建模!这只需要你让构建变得不可能(即提供一个抛出错误的BUILDALL)在角色中,而不是“虚拟”方法中。Moose::Role随后将检查它是否已使用可用的方法组合到一个类中,我已尝试运行代码,然后将覆盖替换为my_ac_sub
,但突然间,它就如预期的那样工作了。“修复”有什么问题吗?(免责声明:我对Moose不熟悉)。除了基类不再提供“抽象”方法外,什么都没有。它只是一个常规的基类,这就是您要寻找的吗?而且它在所有子类中的性能都很高。我愿意看到一个真正的解决办法。我认为这是一个很好的解决办法。它不“感觉干净”,但我会提交一个愿望清单增强这一点。谢谢你的回答。