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;