5

アロハ!

私は Authable と呼ばれる Moose クラスで忙しく定義している役割を持っています。このクラスは、将来何らかの形式の認証を必要とする可能性のあるクラスに本質的に構成されています。それはかなり単純な役割です。全体は次のとおりです。

package Trello::API::Roles::Authable;

use Moose::Role;

#authentication information
has key => (
    is => "rw",
    isa => "Str",
);

has token => (
    is => "rw",
    isa => "Str",
);

1;

なんらかの理由で、複数の異なるステートメントを使用して、つまり「Trello::API::Roles::Authable」を使用してクラスに構成しようとすると、または "Roles::Authable" を使用。

私は一貫してこの同じエラーメッセージを受け取ります:You can only consume roles, Roles::Authable is not a Moose role.

なぜこれが起こっているのでしょうか?

編集!

余談ですが、Moose::Role の実際のソースを確認したところ、次のようなことがわかりました。

    unless ($meta && $meta->isa('Moose::Meta::Role') ) {
        require Moose;
        Moose->throw_error( "You can only consume roles, "
                . $role->[0]
                . " is not a Moose role" );
    }

これはエラーが発生している場所のようです。そのため、何らかの理由で、実装しているロールがメタクラスのロールであることを示していないようです。私は間違っているかもしれませんが!どんな助けでも大歓迎です。

もう一つの便利な編集!

おまけ: with ルーチンが呼び出されるコード コンテキスト。

package Trello::API::Resource;

use Moose;
use URI::Escape;
use LWP::UserAgent;


with 'Roles::Authable';

これを行うと、Roles/Authable.pm を試して消費することをインテリジェントに認識しますが、何らかの理由で機能しません!

4

2 に答える 2

1

まず第一に、技術的には本当にwith 'Trello::API::Roles::Authable'.

つまり、基本的な Moose で実装されているとは思えないものを求めています。以前に汎用名前空間プールのアイデアを使用しました。それらは、半匿名サービスを提供できるユニバーサル名前空間の一種であり、固定名前空間に縛られることはありません。名前空間プールの基本的な考え方を Moose (本当にMOP) のサポートで改良しました。

Perl の西部開拓時代には、次のように、1 つのスタッシュを別のシンボルに割り当てるだけで済みました。

{   no strict 'refs'; 
    *{$short_pkg_name.'::'} = \*{$full_pkg_name.'::'};
};

そして、その 2 つのパッケージはまったく同じものでした。

しかし今は、レキシカルを使ってデータをもう少し保護しています。また、Class::MOP はレキシカル ハッシュでメタ オブジェクトを慎重に保護するため、何か他のものを追加する必要があります。

Class::MOP::store_metaclass_by_name( 
       $short_pkg_name
     , Class::MOP::get_metaclass_by_name( $full_pkg_name )
     );

現在、それらは Perl と MOP にとってまったく同じものです。

したがって、他のパッケージの単なる名前空間リポジトリであるパッケージを作成できます --サポートが追加されましたMOP!

package Namespace::Pool;
use strict;
use warnings;
use Params::Util qw<_POSINT>;

sub import { 
    shift; # It's just me.
    my $full_pkg_name = caller();
    Carp::croak( "'$full_pkg_name' is short enough!" ) 
        unless my $pool_name 
            = shift // [ split /::/, $full_pkg_name ]->[-2]
            ;
    Carp::croak( "'::$pool_name\::' not found in '$full_pkg_name'" ) 
        unless (  _POSINT( my $pos = rindex( $full_pkg_name, "::$pool_name\::" ))
               or my $is_short = _POSINT( index( $pool_name, '::' ))
               ); 
    my $short_pkg_name 
        = $is_short ? $poll_name 
        :             substr( $full_pkg_name, $pos + 2 )
        ;
    {   no strict 'refs'; 
        if ( %{$short_pkg_name.'::'} ) { 
            Carp::croak( "You have already defined $short_pkg_name!" );
        }
        *{$short_pkg_name.'::'} = \*{$full_pkg_name.'::'};
    };

    if ( my $meta = Class::MOP::get_metaclass_by_name( $full_pkg_name )) { 
        Class::MOP::store_metaclass_by_name( $short_pkg_name, $meta );
    }
    return;
}

したがって、Role パッケージでは、次のことができます。

package Trello::API::Roles::Authable;
use strict;
use warnings;
use Moose::Role;
use Namespace::Pool 'Roles';
...

そして、「ロール」の名前空間から利用できることを知っておいてください。

于 2012-08-01T18:03:59.647 に答える
0

私の場合、誤って自分のロールに「Test」という名前を付けただけでしたが、システムには「Test」という名前のモジュールが既にインストールされていたため、Moose は、作成した新しい Moose ロールではなく、そのモジュールを使用したいと考えました。役割ごとに名前を「テスト可能」に変更すると、すべて正常に機能しました。

于 2014-01-23T05:49:19.203 に答える