7

Java の抽象クラスのように動作する Moose::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;

私は何か間違ったことをしていますか?私が達成しようとしていることは、別の方法で行われるべきですか? 私がやろうとしていることは、まったく行われるべきではありませんか?

4

2 に答える 2

5

使い方が間違っていたことが判明。チケットを開いたところ、これを行う正しい方法が示されました。

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;

この変更を行うと、目的の効果が得られます。

于 2013-10-08T12:53:20.243 に答える
2

少し前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
これ
それ
...そしてその他
于 2013-09-23T20:41:10.997 に答える