【问题标题】:Accessing a MooseX::ClassAttribute in a Moose::Role在 Moose::Role 中访问 MooseX::ClassAttribute
【发布时间】:2012-05-24 03:29:34
【问题描述】:

这就是难题。我使用 Moose::Role 作为接口,其中具体类必须实现角色定义的所需属性构建器。该角色还定义了一些对属性执行逻辑的方法。这是我正在尝试做的精简版。

package Parent;
use Moose::Role;
requires '_build_permission_level';

has 'permission_level' => (
    is => 'ro',
    isa => Int,
    lazy_build => 1,
);

use constant {
    LEVEL1 = 1,
    LEVEL2 = 2,
    LEVEL3 = 3,
};

sub can_do_action {
    my $self = shift;
    return $self->permission_level() >= LEVEL2;
}

package Child;
use Moose;
with 'Parent';

sub _build_permission_level { return Parent->LEVEL3; }

显然,我有许多子类,具有不同的权限级别。现在这行得通,但效率极低。所有子实例将始终具有相同的权限级别,但我必须实例化它只是为了询问它是否可以执行操作。当批量运行 10,000 次时,你就明白了。

因此,我想将 permission_level 设为类属性。以 Moose-y 方式解决效率问题。注意 permission_level 如何不再需要 $self。

package Parent;
use Moose::Role;
use MooseX::ClassAttribute;
requires '_build_permission_level';

class_has 'permission_level' => (
    is => 'ro',
    isa => Int,
    builder => '_build_permission_level',
);

use constant {
    LEVEL1 = 1,
    LEVEL2 = 2,
    LEVEL3 = 3,
};

sub can_do_action {
    return permission_level() >= LEVEL2;
}

package Child;
use Moose;
with 'Parent';

sub _build_permission_level { return Parent->LEVEL3; }

这会因未定义的子例程错误而死,找不到 Parent::permission_level。所以父母不知道permission_level。真的吗?我很困惑它如何无法访问自己的类属性。我一定错过了一些非常简单的东西。但更根本的是,我应该如何让 Parent 为 Child 提供的类属性提供逻辑?

【问题讨论】:

    标签: perl moose


    【解决方案1】:

    错误表明在编译时不存在子Parent::permission_level。这是真的:hasclass_has 是运行时结构;编译 can_do_action 中的调用时,sub 尚未创建。

    真正的问题是您在调用类方法时使用了错误的语法。重写can_do_action 这样:

    sub can_do_action {
        my ($class) = @_;
    
        return $class->permission_level >= LEVEL2;
    }
    

    它应该可以正常工作。与普通函数调用不同,方法调用直到运行时才会解析,此时Parent::permission_level 将存在。

    【讨论】:

    • 是的,这就是我所缺少的简单事情。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多