阿罗哈!
我有一个角色,我正在忙于在名为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.
知道为什么会这样吗?
编辑!
只是旁注,我检查了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" );
}
这似乎是错误发生的地方,所以几乎看起来由于某种原因,我正在实现的角色并不是说它是元类中的一个角色。虽然我可能弄错了!任何帮助将不胜感激。
另一个方便的编辑!
Bonus:代码上下文,其中调用with例程。
package Trello::API::Resource;
use Moose;
use URI::Escape;
use LWP::UserAgent;
with 'Roles::Authable';
当我这样做时,它会智能地知道尝试使用Roles / Authable.pm,但无论出于何种原因,它都无法正常运行!
答案 0 :(得分:1)
首先,我必须同意Piers的技术,你真的应该称之为with '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';
...
并且知道它可以从“角色”的命名空间中获得。
答案 1 :(得分:0)
在我的情况下,我只是不小心将我的角色命名为'Test',但我的系统上已经安装了一个名为'Test'的模块,因此Moose认为我想要使用该模块而不是新的Moose角色I' d创建。一旦我通过角色重命名为'Testable',它一切正常。