首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为MooseX::ClassAttribute编写Moose::Role的构建器

为MooseX::ClassAttribute编写Moose::Role的构建器
EN

Stack Overflow用户
提问于 2016-01-19 23:05:43
回答 1查看 96关注 0票数 0

我想定义一个具有Class属性和构建器的角色。不管我试过什么都失败了。我找到了两个解决办法:

  1. 不是使用class属性,而是使用普通属性。这在我的情况下是有问题的,因为我想修改我的实际代码中的属性(对于所有实例)。
  2. 将构建器放入类中(而不是角色)。这也是有问题的,因为它意味着修改所有使用此角色的类。

下面是一个很小的例子:

代码语言:javascript
复制
package MyRole;
use Moose::Role;
use MooseX::ClassAttribute;

sub _build_value {
    return "in MyRole";
}

class_has 'value' => (
    is => 'ro',
    isa => 'Str',
    builder => '_build_value',
);

1;

package Appli;
use Moose;

with 'MyRole';

1;

package main;

my $e=Appli->new();

print $e->value, "\n";

其结果是:

代码语言:javascript
复制
$ perl ./test.pl 
Appli does not support builder method '_build_value' for attribute 'value' at /usr/share/perl5/MooseX/ClassAttribute/Trait/Attribute.pm line 81.
Class::MOP::Class:::around(CODE(0x13d6c78), Moose::Meta::Class::__ANON__::SERIAL::11=HASH(0x1982460), "Appli") called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Class/MOP/Method/Wrapped.pm line 164
Moose::Meta::Class::__ANON__::SERIAL::11::_wrapped__call_builder(Moose::Meta::Class::__ANON__::SERIAL::11=HASH(0x1982460), "Appli") called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Class/MOP/Method/Wrapped.pm line 95
Moose::Meta::Class::__ANON__::SERIAL::11::_call_builder(Moose::Meta::Class::__ANON__::SERIAL::11=HASH(0x1982460), "Appli") called at /usr/share/perl5/MooseX/ClassAttribute/Trait/Attribute.pm line 54
MooseX::ClassAttribute::Trait::Attribute::_initialize(Moose::Meta::Class::__ANON__::SERIAL::11=HASH(0x1982460), Moose::Meta::Class::__ANON__::SERIAL::10=HASH(0x19683d0)) called at /usr/share/perl5/MooseX/ClassAttribute/Trait/Attribute.pm line 32
Class::MOP::Class:::after(Moose::Meta::Class::__ANON__::SERIAL::11=HASH(0x1982460), Moose::Meta::Class::__ANON__::SERIAL::10=HASH(0x19683d0)) called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Class/MOP/Method/Wrapped.pm line 57
Moose::Meta::Class::__ANON__::SERIAL::11::_wrapped_attach_to_class(Moose::Meta::Class::__ANON__::SERIAL::11=HASH(0x1982460), Moose::Meta::Class::__ANON__::SERIAL::10=HASH(0x19683d0)) called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Class/MOP/Method/Wrapped.pm line 95
Moose::Meta::Class::__ANON__::SERIAL::11::attach_to_class(Moose::Meta::Class::__ANON__::SERIAL::11=HASH(0x1982460), Moose::Meta::Class::__ANON__::SERIAL::10=HASH(0x19683d0)) called at /usr/share/perl5/MooseX/ClassAttribute/Trait/Class.pm line 66
MooseX::ClassAttribute::Trait::Class::_attach_class_attribute(Moose::Meta::Class::__ANON__::SERIAL::10=HASH(0x19683d0), Moose::Meta::Class::__ANON__::SERIAL::11=HASH(0x1982460)) called at /usr/share/perl5/MooseX/ClassAttribute/Trait/Mixin/HasClassAttributes.pm line 40
MooseX::ClassAttribute::Trait::Mixin::HasClassAttributes::add_class_attribute(Moose::Meta::Class::__ANON__::SERIAL::10=HASH(0x19683d0), Moose::Meta::Class::__ANON__::SERIAL::11=HASH(0x1982460)) called at /usr/share/perl5/MooseX/ClassAttribute/Trait/Class.pm line 41
Class::MOP::Class:::around(CODE(0x17fae38), Moose::Meta::Class::__ANON__::SERIAL::10=HASH(0x19683d0), Moose::Meta::Class::__ANON__::SERIAL::11=HASH(0x1982460)) called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Class/MOP/Method/Wrapped.pm line 164
Moose::Meta::Class::__ANON__::SERIAL::10::_wrapped_add_class_attribute(Moose::Meta::Class::__ANON__::SERIAL::10=HASH(0x19683d0), Moose::Meta::Class::__ANON__::SERIAL::11=HASH(0x1982460)) called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Class/MOP/Method/Wrapped.pm line 95
Moose::Meta::Class::__ANON__::SERIAL::10::add_class_attribute(Moose::Meta::Class::__ANON__::SERIAL::10=HASH(0x19683d0), Moose::Meta::Class::__ANON__::SERIAL::11=HASH(0x1982460)) called at /usr/share/perl5/MooseX/ClassAttribute/Trait/Application/ToClass.pm line 44
MooseX::ClassAttribute::Trait::Application::ToClass::_apply_class_attributes(Moose::Meta::Class::__ANON__::SERIAL::8=HASH(0x1a29940), Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x1a27298), Moose::Meta::Class::__ANON__::SERIAL::10=HASH(0x19683d0)) called at /usr/share/perl5/MooseX/ClassAttribute/Trait/Application.pm line 13
Class::MOP::Class:::after(Moose::Meta::Class::__ANON__::SERIAL::8=HASH(0x1a29940), Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x1a27298), Moose::Meta::Class::__ANON__::SERIAL::10=HASH(0x19683d0)) called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Class/MOP/Method/Wrapped.pm line 57
Moose::Meta::Class::__ANON__::SERIAL::8::_wrapped_apply_attributes(Moose::Meta::Class::__ANON__::SERIAL::8=HASH(0x1a29940), Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x1a27298), Moose::Meta::Class::__ANON__::SERIAL::10=HASH(0x19683d0)) called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Class/MOP/Method/Wrapped.pm line 95
Moose::Meta::Class::__ANON__::SERIAL::8::apply_attributes(Moose::Meta::Class::__ANON__::SERIAL::8=HASH(0x1a29940), Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x1a27298), Moose::Meta::Class::__ANON__::SERIAL::10=HASH(0x19683d0)) called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Moose/Meta/Role/Application.pm line 59
Moose::Meta::Role::Application::apply(Moose::Meta::Class::__ANON__::SERIAL::8=HASH(0x1a29940), Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x1a27298), Moose::Meta::Class::__ANON__::SERIAL::10=HASH(0x19683d0)) called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Moose/Meta/Role/Application/ToClass.pm line 31
Moose::Meta::Role::Application::ToClass::apply(Moose::Meta::Class::__ANON__::SERIAL::8=HASH(0x1a29940), Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x1a27298), Moose::Meta::Class::__ANON__::SERIAL::10=HASH(0x19683d0)) called at /usr/share/perl5/MooseX/ClassAttribute/Trait/Application/ToClass.pm line 27
Class::MOP::Class:::around(CODE(0x14ae360), Moose::Meta::Class::__ANON__::SERIAL::8=HASH(0x1a29940), Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x1a27298), Moose::Meta::Class=HASH(0x175d658), HASH(0x1a22b28)) called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Class/MOP/Method/Wrapped.pm line 164
Moose::Meta::Class::__ANON__::SERIAL::8::_wrapped_apply(Moose::Meta::Class::__ANON__::SERIAL::8=HASH(0x1a29940), Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x1a27298), Moose::Meta::Class=HASH(0x175d658), HASH(0x1a22b28)) called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Class/MOP/Method/Wrapped.pm line 95
Moose::Meta::Class::__ANON__::SERIAL::8::apply(Moose::Meta::Class::__ANON__::SERIAL::8=HASH(0x1a29940), Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x1a27298), Moose::Meta::Class=HASH(0x175d658), HASH(0x1a22b28)) called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Moose/Meta/Role.pm line 472
Moose::Meta::Role::apply(Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x1a27298), Moose::Meta::Class=HASH(0x175d658)) called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Moose/Util.pm line 172
Moose::Util::_apply_all_roles(Moose::Meta::Class=HASH(0x175d658), undef, "MyRole") called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Moose/Util.pm line 114
Moose::Util::apply_all_roles(Moose::Meta::Class=HASH(0x175d658), "MyRole") called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Moose.pm line 59
Moose::with(Moose::Meta::Class=HASH(0x175d658), "MyRole") called at /usr/lib/x86_64-linux-gnu/perl5/5.22/Moose/Exporter.pm line 419
Moose::with("MyRole") called at ./test.pl line 20

更新:i通过添加“懒惰的=> 1”来解决这个问题。那它就完美地工作了。如果没有“懒惰”,那么在角色完全导入之前很可能会调用构建器。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-22 05:32:51

在这个上下文中使用lazy与其说是一种解决办法,不如说是正确的解决方案。MooseX::ClassAttribute被实现为一个Moose::Role。在MyRole完全组合成Appli之前,Perl调用class_has,后者试图调用_build_value作为Appli类的一种方法。由于该方法还没有被组合成AppliMooseX::ClassAttribute就会出现上述错误。使用lazy将对_build_value的评估推迟到MyRole完全组合成Appli之后。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34888638

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档