将MX :: Declare方法定义为属性触发器

时间:2011-11-11 23:10:17

标签: perl methods moose

以下代码可以正常运行。当它所依赖的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行调用

2 个答案:

答案 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个字符。它的开销较小。