我想定义一个具有Class属性和构建器的角色。不管我试过什么都失败了。我找到了两个解决办法:
下面是一个很小的例子:
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";其结果是:
$ 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”来解决这个问题。那它就完美地工作了。如果没有“懒惰”,那么在角色完全导入之前很可能会调用构建器。
发布于 2016-01-22 05:32:51
在这个上下文中使用lazy与其说是一种解决办法,不如说是正确的解决方案。MooseX::ClassAttribute被实现为一个Moose::Role。在MyRole完全组合成Appli之前,Perl调用class_has,后者试图调用_build_value作为Appli类的一种方法。由于该方法还没有被组合成Appli,MooseX::ClassAttribute就会出现上述错误。使用lazy将对_build_value的评估推迟到MyRole完全组合成Appli之后。
https://stackoverflow.com/questions/34888638
复制相似问题