5

私はMooseを使用しており、プロジェクトでメソッド呼び出しをラップする必要があります。私のラッピングコードが最も外側の修飾子であることが重要です。これまでに行ったことは、メソッド修飾子をMooseロールに配置し、次のようにクラスの最後にそのロールを適用することです。

use Moose::Util;
Moose::Util::apply_all_roles(__PACKAGE__->meta, ('App:Roles::CustomRole'));
__PACKAGE__->meta->make_immutable;

これにより、自分のロールの修飾子が最後に定義されていることを合理的に確認できるため、「前」と「後」の正しい動作が得られます。(役割の「前」と「後」は、最初と最後と呼ばれます。)

もともとはこれで十分だと思っていましたが、今は「アラウンド」と同じようにメソッドをラップする必要があります。Mooseが構築されているClass::MOPは、最初に「around」修飾子を適用するため、「before」の後と「after」の前に呼び出されます。

詳細については、修飾子の現在の呼び出し順序を次に示します。

CUSTOM ROLE before
    before 2
       before 1
           CUSTOM ROLE around
               around
                   method
               around
           CUSTOM ROLE around
       after 1
    after 2
 CUSTOM ROLE AFTER

私は本当にこのようなものが必要です:

CUSTOM ROLE before
    CUSTOM ROLE around
        before 2
           before 1
               around
                   method
               around
           after 1
        after 2
    CUSTOM ROLE around
 CUSTOM ROLE AFTER

「around」修飾子を適用/呼び出したい場所に配置する方法についてのアイデアはありますか?シンボルテーブルのハッキングを実行できることは知っていますが(Class :: MOPがすでに実行しているように)、実際には実行したくありません。

4

2 に答える 2

5

最も簡単な解決策は、CUSTOM ROLE に main メソッドを呼び出すメソッドを定義させ、それをラップすることです。

role MyRole { 
    required 'wrapped_method';
    method custom_role_base_wrapper { $self->wrapped_method(@_) }

    around custom_role_base_wrapper { ... }
    before custom_role_base_wrapper { ... }
}

あなたが抱えている問題は、メソッド以外のものを CUSTOM ROLE でラップしようとしているということです。これは、設計されたものではありません。あなたが提案したような同様のシンボルテーブルハッカーを書く以外に(おそらくMooseの人々の1人がClass::MOPでAPIを公開してそこにたどり着くのを助けると主張することができます)、私が考えることができる唯一の他の解決策は上記のものです。

追加される余分なコール スタック フレームが必要ない場合はcustom_role_base_wrapper、Yuval のSub::Call::Tailまたは使用gotoしてコール スタックを操作する必要があります。

于 2009-11-09T20:37:18.117 に答える
3

私はMooseにかなり慣れていませんが、なぜこれを行うのですか:

use Moose::Util;
Moose::Util::apply_all_roles(__PACKAGE__->meta, ('App:Roles::CustomRole'));

これだけではなく?

with 'App:Roles::CustomRole';

あなたの質問に関しては、ちょっとしたハックですが、aroundメソッドをbeforeandafterメソッドに分割し、クラス定義の最後にロールを適用していただけますか (希望する順序で適用されます)? 絶対に必要な場合は、プライベート属性を使用して 2 つのメソッド間の状態を保存できます。

于 2009-11-09T18:24:44.750 に答える