Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to NOT execute trigger while constructing object

Tags:

perl

moo

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 ;).

like image 311
gib Avatar asked Dec 05 '22 12:12

gib


2 Answers

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.

like image 91
tjwrona1992 Avatar answered Jan 06 '23 22:01

tjwrona1992


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 );
like image 39
ikegami Avatar answered Jan 06 '23 20:01

ikegami