Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 将角色组合到Moose类中不起作用_Perl_Oop_Moose - Fatal编程技术网

Perl 将角色组合到Moose类中不起作用

Perl 将角色组合到Moose类中不起作用,perl,oop,moose,Perl,Oop,Moose,你好 我有一个角色,我正忙着在一个名为Authable的Moose类中定义它,该类基本上被组合成任何将来可能需要某种形式的身份验证的类;这是一个相当简单的角色,全部内容如下: package Trello::API::Roles::Authable; use Moose::Role; #authentication information has key => ( is => "rw", isa => "Str", ); has token => (

你好

我有一个角色,我正忙着在一个名为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”

我始终收到相同的错误消息:
您只能使用角色,角色::Authable不是驼鹿角色。

知道为什么会这样吗

编辑

只是一个旁注,我检查了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的观点,从技术上讲,你真的应该用“Trello::API::Roles::Authable”将其称为

所以,你要求的是一些我没有发现能在基本Moose中实现的东西。 我以前使用过通用名称空间池的思想。它们是一种通用名称空间,您可以向其提供 半匿名服务——没有固定名称空间的锁定。我用Moose(实际上是
MOP
)支持完善了名称空间池的基本概念

在Wild West的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
支持


并且知道它将从“角色”的名称空间中可用。

在我的例子中,我只是意外地将我的角色命名为“Test”,但我的系统上已经安装了一个名为“Test”的模块,因此Moose认为我想使用该模块,而不是我创建的新Moose角色。一旦我将role重命名为“Testable”,一切都很好。

你所说的“多个不同的语句”是什么意思?
是使用“Trello::API::Roles::Authable”还是
使用“Roles::Authable”?因为你似乎没有后一个名字的角色,我的意思是我尝试了多种不同的变体;此时,尝试使用角色的文件是Trello::API::Resource,因此它似乎将Roles::Authable识别为Trello::API::Roles::Authable,并尝试使用该模块。此时,它无法识别模块的位置,因为我没有将它们放入实际的模块目录结构中;我可以随时修改@INC,但现在我只是好奇为什么不能这样使用这个角色。您是在多个文件中声明代码,还是只在一个文件中声明代码?您的类是按什么顺序定义的?您确实应该使用“Trello::API::Roles::Authable”
来执行
,并且为了实现这一点,您应该已经使用
require
d Trello::API::Roles::Authable,或者T::A::R::Authable应该在
lib/Trello/API/Roles/Authable.pm
中定义。在这种情况下,Moose不会对包名施展魔法;它不知道当你用“Roles::Authable”
时,你真正的意思是用“Trello::API::Roles::Authable”
,怎么可能呢?所以,要么把你的软件包放在适当命名的文件中,以便Moose能够找到它们,要么
require
在尝试编写任何东西之前,需要任何奇怪的文件。我非常感谢。在我意识到这个角色起作用后,我最终使用了这个角色的完全限定名,所以,问题解决了,但您的解释非常深入,为实现我的目标提供了一个良好的起点,所以非常感谢您的努力。
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';
...