【问题标题】:How to NOT execute trigger while constructing object如何在构造对象时不执行触发器
【发布时间】:2018-07-15 10:26:59
【问题描述】:

我有这个代码:

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

返回:

$ 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

所以它有效,但是......感觉不对;)。

【问题讨论】:

    标签: perl moo


    【解决方案1】:

    我对@9​​87654321@了解不多,但是在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);
    

    并获得相同的输出。

    【讨论】:

    • 在 Moo 我得到:Can't call method "useTriggers" on unblessed reference
    • 嗯,也许尝试使用 BUILD 子程序代替?摆脱BUILDARGS 并尝试添加sub BUILD { my $self = shift; $self->useTriggers(1); }。同样,我不确定这在Moo 中的作用是否与在Moose 中的作用不同。
    • 尝试编辑答案中的新代码,让我知道它是否有效。 :)
    【解决方案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 );
    

    【讨论】:

    • 如果你有很多这样的属性,你可以写一个子来生成公共访问器(甚至可能是属性)。
    猜你喜欢
    • 2018-05-10
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 2012-09-28
    相关资源
    最近更新 更多