阿罗哈!
我有一个角色,我正在忙于在名为Authable的Moose类中定义,该类基本上被组成任何可能在将来需要某种形式的身份验证的类;这是一个相当简单的角色,这是完整的:
package Trello::API::Roles::Authable; use Moose::Role; #authentication information has key => ( is => "rw",isa => "Str",); has token => ( is => "rw",); 1;
无论出于何种原因,当我尝试使用多个不同的语句将其组成一个类时,即,
与“Trello :: API :: Roles :: Authable”;
要么
与“角色::可自由”;
我一直得到同样的错误信息:你只能消费角色,Roles :: Authable不是Moose角色.
知道为什么会这样吗?
编辑!
只是旁注,我检查了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';
当我这样做时,它会智能地知道尝试使用Roles / Authable.pm,但无论出于何种原因,它都无法正常运行!
解决方法
首先,我必须同意Piers的技术,你真的应该像’Trello :: API :: Roles :: Authable’一样调用它.
所以,你要求我找不到基本的Moose中实现的东西.
我之前使用过通用命名空间池的想法.它们是您可以提供的通用名称空间
半匿名服务 – 没有固定命名空间的锁定.我用Moose(真正的MOP)支持改进了我对命名空间池的基本思想.
在Perl的狂野西部时代,您需要做的就是为另一个符号分配一个存储区,如下所示:
{ no strict 'refs'; *{$short_pkg_name.'::'} = \*{$full_pkg_name.'::'}; };
而且,这两个包是完全相同的东西!
但现在,我们用词汇来保护我们的数据.而且因为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; }
因此,在您的角色包中,您可以执行以下操作:
package Trello::API::Roles::Authable; use strict; use warnings; use Moose::Role; use Namespace::Pool 'Roles'; ...
并且知道它将从“角色”的命名空间中获得.