将 MX::Declare 方法定义为属性触发器
以下代码按我的预期工作。当它所依赖的 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 => '' );
导致类在编译时死亡(如下)。我的匿名方法声明有问题吗?
触发器必须是属性 (foo) 的代码引用,位于 C:/Strawberry/perl/site/lib/Moose/Meta/Attribute.pm 第 423 行 Moose::Meta::Attribute::_process_trigger_option('Moose::Meta::Attribute', 'foo', 'HASH(0x2a5d14c)') 在 C: 调用 /Strawberry/perl/site/lib/Moose/Meta/Attribute.pm 第 299 行 Moose::Meta::Attribute::_process_options('Moose::Meta::Attribute', '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', 在 C:/Straw 调用 'HASH(0x3452184)'、'default'、''、'is'、'rw') berry/perl/site/lib/Moose/Meta/Attribute.pm 第 114 行 Moose::Meta::Attribute::interpolate_class_and_new('Moose::Meta::Attribute', 'foo', 'trigger', 'MooseX::Method::S 签名::Meta::Method=HASH(0x39a421c)', 'isa', 'Str', '默认', '', '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::Signatures::Meta::Method=HASH(0x39a421c)', 'isa', 'Str', '默认'、''、'definition_context'、'HASH(0x3452184)'、'是'、'rw') 调用于 C:/Strawberry/perl/site/lib/Moose/Meta/Class.pm 第 697 行 Moose::Meta::Class::_process_attribute('Moose::Meta::Class=HASH(0x38c79d4)', 'foo', 'trigger', 'MooseX::方法:: 签名::Meta::Method=HASH(0x39a421c)', 'isa', 'Str', '默认', ''、'definition_context'、'HASH(0x3452184)'、'is'、'rw') 调用于 C:/Strawberry/perl/site/lib/Moose/Meta/Class.pm 第 566 行 Moose::Meta::Class::add_attribute('Moose::Meta::Class=HASH(0x38c79d4)', 'foo', 'trigger', 'MooseX::Method::Signa tures::Meta::Method=HASH(0x39a421c)', 'isa', 'Str', '默认', '', 'definition_context'、'HASH(0x3452184)'、'is'、'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=哈希(0x39a421c) ',
'default', '') 在 mx_declare.pl 第 5 行调用 main::ANON() 在 C:/Strawberry/perl/site/lib/MooseX/Declare/Syntax/MooseSetup.pm 行调用 81 MooseX::声明::语法::MooseSetup::匿名('代码(0x38c3a94)') 在 mx_declare.pl 第 13 行调用
The following code works as I'd expect. The cached lazy attribute gets cleared and rebuilt when the foo attribute it depends on is changed.
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;
output:
building lazy
foo is 'baz'
foo is 'baz'
baz
building lazy
foo is 'bar'
How do I, however, use the MX::Declare sugar for the trigger subroutine? Defining foo as:
has foo => ( isa => 'Str', is => 'rw', trigger => method {$self->clearer}, default => '' );
Results in the class dying on compilation (below). Am I doing something wrong with my anonymous method declaration?
Trigger must be a CODE ref on attribute (foo) at
C:/Strawberry/perl/site/lib/Moose/Meta/Attribute.pm line 423
Moose::Meta::Attribute::_process_trigger_option('Moose::Meta::Attribute',
'foo', 'HASH(0x2a5d14c)') called at C:
/Strawberry/perl/site/lib/Moose/Meta/Attribute.pm line 299
Moose::Meta::Attribute::_process_options('Moose::Meta::Attribute',
'foo', 'HASH(0x2a5d14c)') called at 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::Metho
d=HASH(0x39a421c)', 'isa', 'Str', 'definition_context',
'HASH(0x3452184)', 'default', '', 'is', 'rw') called at C:/Straw
berry/perl/site/lib/Moose/Meta/Attribute.pm line 114
Moose::Meta::Attribute::interpolate_class_and_new('Moose::Meta::Attribute',
'foo', 'trigger', 'MooseX::Method::S
ignatures::Meta::Method=HASH(0x39a421c)', 'isa', 'Str', 'default', '',
'definition_context', 'HASH(0x3452184)', 'is', 'r w') called at
C:/Strawberry/perl/site/lib/Moose/Meta/Class.pm line 704
Moose::Meta::Class::_process_new_attribute('Moose::Meta::Class=HASH(0x38c79d4)',
'foo', 'trigger', 'MooseX::Meth
od::Signatures::Meta::Method=HASH(0x39a421c)', 'isa', 'Str',
'default', '', 'definition_context', 'HASH(0x3452184)', 'is ', 'rw')
called at C:/Strawberry/perl/site/lib/Moose/Meta/Class.pm line 697
Moose::Meta::Class::_process_attribute('Moose::Meta::Class=HASH(0x38c79d4)',
'foo', 'trigger', 'MooseX::Method::
Signatures::Meta::Method=HASH(0x39a421c)', 'isa', 'Str', 'default',
'', 'definition_context', 'HASH(0x3452184)', 'is', ' rw') called at
C:/Strawberry/perl/site/lib/Moose/Meta/Class.pm line 566
Moose::Meta::Class::add_attribute('Moose::Meta::Class=HASH(0x38c79d4)',
'foo', 'trigger', 'MooseX::Method::Signa
tures::Meta::Method=HASH(0x39a421c)', 'isa', 'Str', 'default', '',
'definition_context', 'HASH(0x3452184)', 'is', 'rw') called at
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', '') called at
C:/Strawberry/perl/site/lib/Moose/Exporter.pm line 356Moose::has('foo', 'isa', 'Str', 'is', 'rw', 'trigger', 'MooseX::Method::Signatures::Meta::Method=HASH(0x39a421c) ',
'default', '') called at mx_declare.pl line 5
main::ANON() called at C:/Strawberry/perl/site/lib/MooseX/Declare/Syntax/MooseSetup.pm line
81
MooseX::Declare::Syntax::MooseSetup::ANON('CODE(0x38c3a94)')
called at mx_declare.pl line 13
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
method
关键字返回MooseX::Method::Signatures::Meta::Method
类的实例,该类是Moose::Meta: 的子类: :Method
,它是Class::MOP::Method
的子类。Moose 允许使用
default
的方法对象,但不允许使用trigger
的方法对象,后者必须是常规的 coderef。如果您确实想在那里使用
method
关键字,您可能会这样做:但是按照 @cjm 的建议进行操作并仅使用常规的 coderef 可能会更容易(并且更明智):
The
method
keyword returns an instance of theMooseX::Method::Signatures::Meta::Method
class, which is a subclass ofMoose::Meta::Method
, which is a subclass ofClass::MOP::Method
.Moose allows a method object for
default
, but not fortrigger
, which must be a regular coderef.If you really want to use the
method
keyword there, you could probably do:But it's probably easier (and saner) to do what @cjm suggests and just use a regular coderef:
你不能。
method
返回一个对象,而不是普通的 coderef。但是,您可以比method
允许的方式编写得更简洁:这比
method {$self->clearer}
短 3 个字符。而且它的开销更少。You can't.
method
returns an object, not a plain coderef. However, you can write this even more concisely thanmethod
would allow:That's 3 characters shorter than
method {$self->clearer}
. And it has less overhead.