gpt4 book ai didi

perl - 将角色组合成 Moose 类不起作用

转载 作者:行者123 更新时间:2023-12-01 19:44:58 24 4
gpt4 key购买 nike

喂!

我有一个角色,我正忙于在一个名为 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" );
}

这似乎是发生错误的地方,因此几乎似乎出于某种原因,我正在实现的角色并未说明它是元类中的角色。虽然我可能会误会!任何帮助,将不胜感激。

另一个方便的编辑!

奖励:代码上下文,其中调用 with 例程。
package Trello::API::Resource;

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


with 'Roles::Authable';

当我这样做时,它智能地知道尝试使用 Roles/Authable.pm 但无论出于何种原因,它都无法运行!

最佳答案

首先,我必须同意 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;
}

因此,在您的 Role 包中,您可以执行以下操作:
package Trello::API::Roles::Authable;
use strict;
use warnings;
use Moose::Role;
use Namespace::Pool 'Roles';
...

并且知道它可以从“角色”的命名空间中获得。

关于perl - 将角色组合成 Moose 类不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10730190/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com