如何在构造对象时不执行触发器
How to NOT execute trigger while constructing object
我有这个代码:
package Foo;
use Moo;
has attr => ( is => "rw", trigger => 1 );
sub _trigger_attr
{ print "trigger! value:". shift->attr ."\n" }
package main;
use Foo;
my $foo = Foo->new( attr => 1 );
$foo->attr( 2 );
它returns:
$ perl test.pl
trigger! value:1
trigger! value:2
这是 Moo 中触发器的默认记录行为。
如果属性是通过构造函数设置的,我如何禁用触发器执行?
我当然可以这样做:
package Foo;
use Moo;
has attr => ( is => "rw", trigger => 1 );
has useTriggers => ( is => "rw", default => 0 );
sub _trigger_attr
{
my $self = shift;
print "trigger! value:". $self->attr ."\n" if $self->useTriggers
}
package main;
use Foo;
my $foo = Foo->new( attr => 1 );
$foo->useTriggers( 1 );
$foo->attr( 2 );
并得到:
$ perl testt.pl
trigger! value:2
所以它有效,但是......感觉不对;)。
我不太了解Moo
,但是在Moose
中你可以在构造函数之后实现你自己的代码。如果你能在 Moo
中做这样的事情,它会给你想要的效果。
sub BUILD {
my $self = shift;
# Sets "useTriggers" AFTER the object is already constructed.
$self->useTriggers(1);
};
这会导致 useTriggers
在构造之后立即设置,因此触发器将在对象构造之后激活,而不是在构造之前激活。
所以你应该可以写:
my $foo->new(attr => 1);
$foo->attr(2);
并获得相同的输出。
package Foo;
use Moo;
has attr => ( accessor => '_attr' );
sub attr {
my $self = shift;
my $rv = $self->_attr(@_);
print "trigger! value: ", $rv if @_;
return $rv;
}
package main;
use Foo;
my $foo = Foo->new( attr => 1 );
$foo->attr( 2 );
我有这个代码:
package Foo;
use Moo;
has attr => ( is => "rw", trigger => 1 );
sub _trigger_attr
{ print "trigger! value:". shift->attr ."\n" }
package main;
use Foo;
my $foo = Foo->new( attr => 1 );
$foo->attr( 2 );
它returns:
$ perl test.pl
trigger! value:1
trigger! value:2
这是 Moo 中触发器的默认记录行为。
如果属性是通过构造函数设置的,我如何禁用触发器执行?
我当然可以这样做:
package Foo;
use Moo;
has attr => ( is => "rw", trigger => 1 );
has useTriggers => ( is => "rw", default => 0 );
sub _trigger_attr
{
my $self = shift;
print "trigger! value:". $self->attr ."\n" if $self->useTriggers
}
package main;
use Foo;
my $foo = Foo->new( attr => 1 );
$foo->useTriggers( 1 );
$foo->attr( 2 );
并得到:
$ perl testt.pl
trigger! value:2
所以它有效,但是......感觉不对;)。
我不太了解Moo
,但是在Moose
中你可以在构造函数之后实现你自己的代码。如果你能在 Moo
中做这样的事情,它会给你想要的效果。
sub BUILD {
my $self = shift;
# Sets "useTriggers" AFTER the object is already constructed.
$self->useTriggers(1);
};
这会导致 useTriggers
在构造之后立即设置,因此触发器将在对象构造之后激活,而不是在构造之前激活。
所以你应该可以写:
my $foo->new(attr => 1);
$foo->attr(2);
并获得相同的输出。
package Foo;
use Moo;
has attr => ( accessor => '_attr' );
sub attr {
my $self = shift;
my $rv = $self->_attr(@_);
print "trigger! value: ", $rv if @_;
return $rv;
}
package main;
use Foo;
my $foo = Foo->new( attr => 1 );
$foo->attr( 2 );