Определение метода MX :: Declare в качестве триггера атрибута - PullRequest
2 голосов
/ 12 ноября 2011

Следующий код работает так, как я ожидал. Атрибут cached lazy очищается и перестраивается при изменении атрибута foo, от которого он зависит.

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 => '' );

Результаты в классе, умирающем при компиляции (ниже). Что-то не так с объявлением анонимного метода?

Триггер должен быть CODE ref для атрибута (foo) в C: /Strawberry/perl/site/lib/Moose/Meta/Attribute.pm строка 423 Moose :: Meta :: Attribute :: _ process_trigger_option ( 'Moose :: Meta :: Атрибут', 'foo', 'HASH (0x2a5d14c)') вызывается в C: /Strawberry/perl/site/lib/Moose/Meta/Attribute.pm строка 299 Moose :: Meta :: Attribute :: _ process_options ( 'Moose :: Meta :: Атрибут', 'foo', 'HASH (0x2a5d14c)') вызывается в C: / Strawb erry / perl / site / lib / Moose / Meta / Attribute.pm line 88 Moose :: Meta :: Attribute :: new ('Moose :: Meta :: Attribute', 'foo', 'trigger', 'MooseX :: Method :: Signatures :: Meta :: Methods d = HASH (0x39a421c) ',' isa ',' Str ',' Definition_context ', 'HASH (0x3452184)', 'default', '', 'is', 'rw') вызывается в C: / Straw berry / perl / site / lib / Moose / Meta / Attribute.pm line 114 Moose :: Meta :: Attribute :: interpolate_class_and_new ( 'Moose :: Meta :: Атрибут', 'foo', 'trigger', 'MooseX :: Method :: S ignatures :: Meta :: Method = HASH (0x39a421c) ',' isa ',' Str ',' default ',' ', 'Definition_context', 'HASH (0x3452184)', 'is', 'r w') вызывается в C: /Strawberry/perl/site/lib/Moose/Meta/Class.pm строка 704 Moose :: Meta :: Class :: _ process_new_attribute ( 'Moose :: Meta :: Class = HASH (0x38c79d4)', 'foo', 'trigger', 'MooseX :: Meth od :: Подписи :: Meta :: Method = HASH (0x39a421c) ',' isa ',' Str ', 'default', '', Definition_context ',' HASH (0x3452184) ',' is ',' rw ') вызывается в C: /Strawberry/perl/site/lib/Moose/Meta/Class.pm строка 697 Moose :: Meta :: Class :: _ process_attribute ( 'Moose :: Meta :: Class = HASH (0x38c79d4)', 'foo', 'trigger', 'MooseX :: Method :: Подписи :: Meta :: Method = HASH (0x39a421c) ',' isa ',' Str ',' default ', '', 'definition_context', 'HASH (0x3452184)', 'is', 'rw') вызывается в C: /Strawberry/perl/site/lib/Moose/Meta/Class.pm line 566 Мус :: Мета :: Класс :: add_attribute ( 'Мус :: Мета :: Класс = HASH (0x38c79d4)', 'foo', 'trigger', 'MooseX :: Method :: Signa tures :: Meta :: Method = HASH (0x39a421c) ',' isa ',' Str ',' default ',' ', 'Definition_context', 'HASH (0x3452184)', 'is', 'rw') вызывается в C: /Strawberry/perl/site/lib/Moose.pm line 77 Moose :: has ('Moose :: Meta :: Class = HASH (0x38c79d4)', 'foo', 'isa', 'Str', 'is', 'rw', 'trigger', 'MooseX :: Method: : Si, 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 81 MooseX :: Объявляет :: Синтаксис :: MooseSetup :: ANON ( 'CODE (0x38c3a94)') вызывается в строке mx_declare.pl 13

Ответы [ 2 ]

2 голосов
/ 12 ноября 2011

Ключевое слово method возвращает экземпляр класса MooseX::Method::Signatures::Meta::Method, который является подклассом Moose::Meta::Method, который является подклассом Class::MOP::Method.

Moose допускает объект метода для default, но не для trigger, который должен быть обычным coderef.

Если вы действительно хотите использовать ключевое слово method, вы можете сделать:

trigger => method { $self->clearer }->body,

Новероятно, проще (и разумнее) сделать то, что предлагает @cjm, и просто использовать обычный код ссылки:

trigger => sub { shift->clearer },
1 голос
/ 12 ноября 2011

Вы не можете. method возвращает объект, а не простой coderef. Однако вы можете написать это даже более кратко, чем допустит method:

has foo => ( isa => 'Str', is => 'rw', trigger => sub {shift->clearer}, default => '' );

Это на 3 символа короче method {$self->clearer}. И у него меньше накладных расходов.

...