以下代码可以正常运行。当它所依赖的foo属性发生更改时,缓存的lazy属性将被清除并重建。
use MooseX::Declare;
use 5.010;
class Test {
has foo => ( isa => 'Str', is => 'rw', trigger => sub {my $self = shift; $self->clearer}, default => '' );
has lazy => ( isa => 'Str', is => 'ro', lazy => 1, clearer => 'clearer',
default => method { say 'building lazy'; return "foo is '".$self->foo."'"; },
);
method say ( ) {
say $self->lazy;
}
}
my $inst = Test->new( foo => 'baz' );
$inst->say;
$inst->say;
say $inst->foo();
$inst->foo('bar');
$inst->say;
输出:
building lazy
foo is 'baz'
foo is 'baz'
baz
building lazy
foo is 'bar'
但是,如何使用MX :: Declare糖作为触发子程序?将foo定义为:
has foo => ( isa => 'Str', is => 'rw', trigger => method {$self->clearer}, default => '' );
在编译时死亡的类(下面)。我的匿名方法声明有问题吗?
触发器必须是属性(foo)处的CODE引用 C:/Strawberry/perl/site/lib/Moose/Meta/Attribute.pm第423行 穆斯::元::属性:: _ process_trigger_option( '穆斯::元::属性', 'foo','HASH(0x2a5d14c)')在C调用: /Strawberry/perl/site/lib/Moose/Meta/Attribute.pm第299行 穆斯::元::属性:: _ process_options( '穆斯::元::属性', 'foo','HASH(0x2a5d14c)')在C:/ Strawb调用 erry / perl / site / lib / Moose / Meta / Attribute.pm第88行 Moose :: Meta :: Attribute :: new('Moose :: Meta :: Attribute','foo','trigger','MooseX :: Method :: Signatures :: Meta :: Metho d = HASH(0x39a421c)','isa','Str','definition_context', 'HASH(0x3452184)','默认','','是','rw')在C:/ Straw调用 berry / perl / site / lib / Moose / Meta / Attribute.pm第114行 穆斯::元::属性:: interpolate_class_and_new( '穆斯::元::属性', 'foo','触发','MooseX :: Method :: S ignatures :: Meta :: Method = HASH(0x39a421c)','isa','Str','default','', 'definition_context','HASH(0x3452184)','是','r w')调用于 C:/Strawberry/perl/site/lib/Moose/Meta/Class.pm第704行 驼鹿::元::类:: _ process_new_attribute( '驼鹿::元::类= HASH(0x38c79d4)', 'foo','触发','MooseX :: Meth od :: Signatures :: Meta :: Method = HASH(0x39a421c)','isa','Str', 'default','','definition_context','HASH(0x3452184)','是','rw') 叫做C:/Strawberry/perl/site/lib/Moose/Meta/Class.pm第697行 驼鹿::元::类:: _ PROCESS_ATTRIBUTE( '驼鹿::元::类= HASH(0x38c79d4)', 'foo','触发','MooseX :: Method :: 签名:: Meta :: Method = HASH(0x39a421c)','isa','Str','default', '','definition_context','HASH(0x3452184)','是','rw')调用于 C:/Strawberry/perl/site/lib/Moose/Meta/Class.pm第566行 驼鹿::元::类:: ADD_ATTRIBUTE( '驼鹿::元::类= HASH(0x38c79d4)', 'foo','触发','MooseX :: Method :: Signa tures :: Meta :: Method = HASH(0x39a421c)','isa','Str','default','', 'definition_context','HASH(0x3452184)','是','rw')调用于 C:/Strawberry/perl/site/lib/Moose.pm第77行 Moose :: has('Moose :: Meta :: Class = HASH(0x38c79d4)','foo','isa','str','is','rw','trigger','MooseX :: Method: :硅 gnatures :: Meta :: Method = HASH(0x39a421c)','default','')调用 C:/Strawberry/perl/site/lib/Moose/Exporter.pm第356行
Moose::has('foo', 'isa', 'Str', 'is', 'rw', 'trigger', 'MooseX::Method::Signatures::Meta::Method=HASH(0x39a421c) ',
'default','')在mx_declare.pl第5行调用 main :: ANON ()调用C:/Strawberry/perl/site/lib/MooseX/Declare/Syntax/MooseSetup.pm line 81 MooseX ::声明::语法:: MooseSetup ::的 ANON ( 'CODE(0x38c3a94)') 在mx_declare.pl第13行调用
答案 0 :(得分:2)
method
关键字返回MooseX::Method::Signatures::Meta::Method
类的实例,该类是Moose::Meta::Method
的子类,是Class::MOP::Method
的子类。
Moose允许default
的方法对象,但不允许trigger
的方法对象,它必须是常规的coderef。
如果你真的想在那里使用method
关键字,你可能会这样做:
trigger => method { $self->clearer }->body,
但是,做@cjm所建议的并且只使用常规的coderef可能更容易(也更安全):
trigger => sub { shift->clearer },
答案 1 :(得分:1)
你做不到。 method
返回一个对象,而不是简单的coderef。但是,您可以比method
允许的更简洁地写出:
has foo => ( isa => 'Str', is => 'rw', trigger => sub {shift->clearer}, default => '' );
比method {$self->clearer}
短3个字符。它的开销较小。