我想在每次设置时修改属性的值,无论是在构造函数中还是在编写者中完成,(我都不会使用' ;在这种情况下,构建者'或默认')。基本上,属性(不是必需的' Str'类型)被传递给构造函数,在某些情况下我想在此之后修改它的值,但是在每个场景中我都想对它做一些正则表达式(例如)
我的第一种方法是使用BUILDARGS和around方法,两者都使用相同的正则表达式函数,但后来我想知道强制。唯一的问题是我不知道如何创建一个无论如何都会强迫强制的子类型/类型定义。
例如:
package Foo;
use Moose::Util::TypeConstraints;
subtype 'Foo::bar' => as 'Str';
coerce 'Foo::bar'
=> from 'Str'
=> via {
$_ =~ s/some_stuff//g;
$_ =~ s/other_stuff//g;
$_ =~ s/some_other_stuff//g;
};
has 'bar' => (isa => 'Foo:bar', coerce => 1);
我不想用'其中'来定义子类型/类型。像
这样的子句subtype 'Foo::bar' => as 'Str' => where {$_ !~ /some_stuff/ && $_ !~ /other_stuff/ && ... };
因为这对我来说似乎很乏味。
编辑:我正在寻找一个全面的解决方案,我不仅可以使用' Str'类型属性还有' ArrayRef',' HashRef'等
答案 0 :(得分:0)
听起来像是想要trigger。
package Foo;
use Moose;
has 'bar' => (
is => 'rw',
isa => 'Str',
trigger => sub {
my ( $self, $value, $old_value ) = @_;
say 'in trigger';
# prevent infinite loop
return if $old_value && $old_value eq $value;
my $original_value = $value;
$value =~ s/some_stuff//g;
$value =~ s/other_stuff//g;
$value =~ s/some_other_stuff//g;
# prevent infinite loop
return if $value eq $original_value;
say '... setting new value';
$self->bar($value);
},
);
package main;
my $foo = Foo->new( bar => 'foo some_stuff and other_stuff and some_more_stuff' );
say $foo->bar;
我想在每次设置时修改属性的值,无论如何 如果它是在构造函数或作者之间完成的(我不会使用 '助洗剂'或者'默认'在那种情况下)
这正是触发器的作用。医生几乎逐字逐句地说了你所要求的:
注意:触发器仅在您在构造函数中或使用编写器分配属性时触发。默认值和构建值不会导致触发器被触发。
编辑:inifite循环检测中存在错误。它现在可以工作,并将在第二次调用时停止。我把调试输出留下来演示。
in trigger
... setting new value
in trigger
foo and and some_more_stuff