Perl 如何有效地对Moose属性应用正则表达式替换?

Perl 如何有效地对Moose属性应用正则表达式替换?,perl,attributes,moose,Perl,Attributes,Moose,我有一个 package Test; use Moose; has 'attr' => ( is => 'rw', isa => 'Str' ); 在一个方法中,我想在属性上应用s/pattern/string/g。出于Moose中记录的原因(基本上是为了正确支持多态性),我不想直接访问$self->{attr},因此一个简单的: $self->{attr} =~ s/pattern/string/g; 这不是一种选择。我怎样才能用Moose快速高效地完成这项工作,而

我有一个

package Test;
use Moose;
has 'attr' => ( is => 'rw', isa => 'Str' );
在一个方法中,我想在属性上应用
s/pattern/string/g
。出于Moose中记录的原因(基本上是为了正确支持多态性),我不想直接访问
$self->{attr}
,因此一个简单的:

$self->{attr} =~ s/pattern/string/g;
这不是一种选择。我怎样才能用Moose快速高效地完成这项工作,而且代码很少但清晰

我提出的选择是:

1) 使用临时变量和常用的getter/setter方法:

my $dummy = $self->attr;
$dummy =~ s/pattern/string/g;
$self->attr($dummy);
2) 使用左侧的attr getter/setter:

$self->attr($dummy) =~ s/pattern/string/g;
但这显然是一个错误

无法在Test.pm修改非左值子例程调用 第58行,第29行

有没有一种方法可以将驼鹿访问器用作访问器

3) 使用

重新定义属性:

has 'attr' => ( is => 'rw', isa => 'Str', traits  => ['String'],
                handles => { replace_attr => 'replace'}  );
然后在方法中使用:

$self->replace_attr('pattern', 'string');
然而,文档明确指出,无法指定
/g
标志


有没有现成的优雅、简单、有点效率的方法?

我过去使用过这种方法,我认为它在效率和清洁度方面似乎适合我的一般使用。它还与
/g
修饰符一起使用

$self->attr( $self->attr =~ s/pattern/string/gr );
我怀疑这和第一个临时变量的例子一样,只是对我们隐藏了它

请注意,要使用
/r
修饰符(返回替换结果而不修改原始结果),需要Perl 5.14+

我的选项(2)并提供使用的想法:

这允许使用简单的语法:

$self->attr($dummy) =~ s/pattern/string/g;
在内部,它使用和特性,因此这种方法存在性能开销,这会影响对“traited”属性的每次访问,而不仅仅是将其用作左侧的访问。感谢LeoNerd和ikegami对我先前发言的更正意见


因此,经模块文档确认,Moose的类型检查仍然有效,触发器被触发。

相关:为什么要这样做?也许将它实现为编写器的
左右
修饰符或触发器比在其他地方使用它更有意义?如果访问器是左值子对象,它将直接有效地访问
$self->{attr}
,除非创建了神奇的返回值,减慢不需要的访问速度。这比我列出的尝试时间短,因此是一个很好的建议。如果我们可以避免代码冗余,那就好了。尽管我用我自己的答案作为解决方案,尽管我没有(目前也不会)做性能基准测试,但我还是把你的作为解决方案,因为在我们得到的只是少一点代码冗余的情况下,为每次访问支付性能惩罚不是一个明智的想法。虽然我强烈反对这种冗余,但这一个是非常局部的(两个attr名称紧挨着彼此,并且可以很好地维护。嗯,是吗?最近的阅读(版本0.981)声称所有的验证和触发器都工作得很好。@LeoNerd是对的。它返回一个神奇的标量,而不是返回
$self->{attr}
直接用于正确进行类型检查。我相信这会大大增加访问属性的成本。@LeoNerd和ikegami:这是一个明显的错误:我读了文档,写了相反的内容。谢谢您纠正我,我已经更新了答案。
$self->attr($dummy) =~ s/pattern/string/g;