【问题标题】:using aliased with Moose doesn't seem to work when declaring classes在声明类时,使用 Moose 的别名似乎不起作用
【发布时间】:2017-07-11 13:52:15
【问题描述】:

我对 Perl 有点陌生。我正在尝试以下列方式定义/使用一个类:

package A::B::C;
use strict;
use warnings;
use Moose;
use aliased 'A::B::D';
has 'attribute' => (isa => 'ArrayRef[D]', is => 'ro', required => 1);

创建对象时:

use aliased 'A::B::C';
use aliased 'A::B::D';
my $aref = [D->new()];
C->new($aref);

然而,正如 Moose 抱怨的那样,这失败了:

Attribute (attribute) does not pass the type constraint because: Validation failed for 'ArrayRef[D]' with value ARRAY(0x7f2b658b51c0)

但是,如果我切换到不使用别名,它会起作用(当然应该):

package A::B::C;
use strict;
use warnings;
use Moose;
use A::B::D;
has 'attribute' => (isa => 'ArrayRef[A::B::D]', is => 'ro', required => 1);

我的问题是为什么使用别名位不适用于 Moose?

谢谢

【问题讨论】:

    标签: perl perl-module moose


    【解决方案1】:

    Moose 不知道use aliased。 pragma use aliased 是基于 Perl 的 hack;它所做的只是创建一个返回类名的短名称的子例程。所以

    use aliased 'A::B::D';
    

    等价于

    use A::B::D;
    
    sub D() { 'A::B::D' }
    

    (见aliased.pm#L45)

    然后,当你说D->new() 之类的东西时,Perl 注意到有一个名为D 的子例程(常量)并将D 解释为子例程调用,然后对结果进行方法调用。 (而不是像通常那样将D 解释为字符串常量)。即使对于 Perl,D 也不是真正的包名;只是一个类似于包名的东西!

    此外,Moose 有自己的解析类型声明的系统(这就是为什么您可以像以前那样将它们作为字符串提供)和它自己的类型声明的全局概念。这些都不知道aliased,所以 Moose 使用其默认行为,将无法识别的类型视为(全局)包名。

    如果您了解aliased 的工作原理,您可以通过这样做来利用它

    has 'attribute' => (isa => 'ArrayRef['.D.']', is => 'ro', required => 1);
    

    但最好记住这一点

    Type names are global throughout the current Perl interpreter

    要么在任何地方使用完全限定的包名作为类型,要么使用Type::Tiny 并写入

    package A::B::C;
    
    use Moose;
    
    use aliased 'A::B::D';
    
    use Types::Standard qw/ ArrayRef /;
    use Type::Utils qw( class_type );
    
    has 'attribute' => (isa => ArrayRef[class_type D], is => 'ro', required => 1);
    

    (注意D 周围没有引号,这可能只是因为use aliased!)。

    (Type::Tiny 可能会比 Moose 类型更快,所以你可能还是要考虑一下)。

    【讨论】:

    • 这是使用短名称进行导入的标准/推荐方式吗?我要确保的是,我最终使用的方法没有任何相关的陷阱,并且仅在用作指定整个路径的替代品时才有效。
    猜你喜欢
    • 2021-10-29
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 2011-11-04
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    相关资源
    最近更新 更多