2012-05-24 47 views
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」;

我一直收到此相同的錯誤消息:You can only consume roles, Roles::Authable is not a 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"); 
    } 

這似乎是個錯誤的現象發生,所以它幾乎似乎出於某種原因,我正在實現的角色並不是說它是元類中的一個角色。雖然我可能錯了!任何幫助,將不勝感激。

另一個方便的編輯!

獎勵:其中調用了例程的代碼上下文。

package Trello::API::Resource; 

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


with 'Roles::Authable'; 

,我這樣做時,智能知道要嘗試和消費角色/ Authable.pm但無論出於何種原因,它只是無法正常使用!

+1

你是什麼意思「多個不同的陳述?」你正在用'Trello :: API :: Roles :: Authable''或'with'Roles :: Authable'來做';'?因爲你似乎沒有與後一個名字的角色。 – friedo

+0

[您是否在使用'Moose'或'Any :: Moose'?](http://blogs.perl.org/users/sawyer_x/2012/05/priorities-when-using-anymoose-and-what-mouse- people-should-do.html) – 2012-05-24 02:13:36

+0

我的意思是我嘗試了多種不同的變體;此時,嘗試消費角色的文件是Trello :: API :: Resource,因此它似乎將Roles :: Authable識別爲Trello :: API :: Roles :: Authable,並嘗試使用該模塊。此時,它不會識別模塊的位置,因爲我沒有將它們放入實際的模塊目錄結構中;我總是可以修改@INC,但是現在我只是好奇爲什麼角色不能被消費。 – ozzmotik

回答

1

首先,我必須同意皮爾斯在技術上,你真的應該把它稱爲with 'Trello::API::Roles::Authable'

所以,你要求的東西,我不覺得在基本穆斯實施。 我以前使用過泛型名稱空間池的想法。它們是通用名稱空間,您可以向其提供您的半匿名服務 - 無需鎖定固定名稱空間。我使用Moose(對真實的MOP)支持提煉了我對命名空間池的基本概念。

在Perl的狂野的西部天,所有你需要做的就是一個藏匿分配給符號爲其他,像這樣:

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

而且,這兩個包都是一模一樣的東西!

但是現在我們用詞彙來保護我們的數據。而由於類:: MOP小心翼翼地看守着一個詞彙哈希它的元對象,你需要添加別的東西:

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

現在,他們是同樣的事情到Perl和澳門幣。

因此,您可以創建簡單的包名稱空間存儲庫的其他包 - 現在與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; 
} 

因此,在你的角色包,你可以做到以下幾點:

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

並知道它會從「角色」的命名空間。

+0

我非常感謝。當我意識到它正在工作後,我最終使用了角色的完全限定名稱,所以問題解決了,但是您的解釋非常深入,併爲實現我正在嘗試做的事情提供了一個很好的起點,所以謝謝你非常努力。 – ozzmotik

0

在我的情況下,我只是不小心將角色命名爲'Test',但我的系統上已經有一個名爲'Test'的已安裝模塊,所以Moose認爲我想要使用該模塊而不是新的Moose角色I '創建。一旦我通過角色重新命名爲'可測試',它一切正常。