3

スタンドアロンのユーティリティクラスではなく、親のMooseクラス内からいくつかのヘルパーメソッドを設定する方法を探しています。可能であれば、ヘルパーモジュールを明示的に要求する必要がないため(すべてがextends宣言を介して行われるため)、モジュールにムースシュガーを追加するより透過的な方法になります。

ドキュメントで提供されている例に基づいて、これは大まかに私が目指していることです:

package Parent;

use Moose;

Moose::Exporter->setup_import_methods(
    with_meta => [ 'has_rw' ],
    as_is     => [ 'thing' ],
    also      => 'Moose',
);

sub has_rw {
    my ( $meta, $name, %options ) = @_;
    $meta->add_attribute(
        $name,
        is => 'rw',
        %options,
    );
}

# then later ...
package Child;

use Moose;
extends 'Parent';

has 'name';
has_rw 'size';
thing;

ただし、これは機能しません。

perl -I. -MChild -wle'$obj = Child->new(size => 1); print $obj->size'
演算子がChild.pmの10行目で「has_rw'size'」の近くにあると予想される場所に文字列が見つかりました
        (has_rwを事前に宣言する必要がありますか?)
「has_rw'size'」の近くのChild.pm行10での構文エラー
Child.pmの12行目で「strictsubs」が使用されている間は、ベアワード「thing」は許可されません。
コンパイルはrequireで失敗しました。
BEGINが失敗しました-コンパイルが中止されました。

PS。with Role;また、エクスポートマジックを(ではなく)ロールに移動しようとしましたextends Parent;が、同じエラーが発生します。

4

1 に答える 1

7

これはサポートされておらず、それには十分な理由があります。クラスまたはロールはシュガーメソッドと同じではなく、あるレベルでは異なるものが異なるはずです。問題がMoose+カスタムSugarパッケージを「使用」する必要がある場合は、カスタムSugarパッケージにMooseもエクスポートさせて、例から盗むだけで解決できます。

package MySugar;
use strict;
use Moose::Exporter;

Moose::Exporter->setup_import_methods(
    with_meta => [ 'has_rw' ],
    as_is     => [ 'thing' ],
    also      => 'Moose',
);

sub has_rw {
    my ( $meta, $name, %options ) = @_;
    $meta->add_attribute(
        $name,
        is => 'rw',
        %options,
    );
}

次に、あなたは単に言う:

package MyApp;
use MySugar; # imports everything from Moose + has_rw and thing    
extends(Parent);

has_rw 'name';
has 'size';
thing;

これはMooseX::POE、他のいくつかのパッケージと同様に、どのように機能するかです。クラスは砂糖関数のバンドルではないため、ここで提案しているように砂糖を持ち込むことに反対しextendsます。この2つを混同しないでください。

更新:両方を同時に取り込むための最もクリーンなアプローチは、Moose::Objectに適用されるロールとしてParentを作り直すことです。

package Parent::Methods;
use 5.10.0;
use Moose::Role;

sub something_special { say 'sparkles' }

次に、MySugarのMoose::Exporterへの呼び出しを次のように変更するだけです。

Moose::Exporter->setup_import_methods(
    apply_base_class_roles => 'Parent::Methods',
    with_meta              => ['has_rw'],
    as_is                  => ['thing'],
    also                   => 'Moose',
);

今、あなたは簡単に言うことができます

package MyApp;
use MySugar; 

has_rw 'name';
has 'size';
thing;

package main;
MyApp->new->something_special; # prints sparkles

これはあなたが望んでいた最終的な詳細だと思います。

于 2009-12-02T06:17:14.953 に答える