I have this code:
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 );
It returns:
$ perl test.pl
trigger! value:1
trigger! value:2
This is default, documented behavior of Triggers in Moo.
How can I disable trigger execution if the attribute is set via constructor?
Of course I can do it like this:
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 );
And get:
$ perl testt.pl
trigger! value:2
So it works, but ... it feels wrong ;).
I don't know much about Moo
, but in Moose
you can implement your own code after the constructor. If you can do something like this in Moo
it would give you the desired effect.
sub BUILD {
my $self = shift;
# Sets "useTriggers" AFTER the object is already constructed.
$self->useTriggers(1);
};
This would cause useTriggers
to be set just after construction so the trigger would be active after the object is constructed, but not before it is constructed.
So you should be able to write:
my $foo->new(attr => 1);
$foo->attr(2);
And get the same output.
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 );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With