如何有效地对 Moose 属性应用正则表达式替换?
How to efficiently apply a regex substitution on a Moose attribute?
我有一个
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;
但这显然会引发错误
Can't modify non-lvalue subroutine call at Test.pm
line 58, line 29
有没有办法像 lvalue subs 一样使用 Moose 访问器?
3) 使用 String traits
重新定义属性:
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
修饰符,returns 替换结果而不修改原始值,需要 Perl 5.14+。
我的选择 (2) 和 this question provide the idea to use MooseX::LvalueAttributes:
package Test;
use Moose;
use MooseX::LvalueAttribute 'lvalue';
has 'attr' => ( is => 'rw', isa => 'Str', traits => [lvalue] );
这允许使用简单的语法:
$self->attr($dummy) =~ s/pattern/string/g;
这在内部使用了 Variable::Magic and the perlsub lvalue 功能,因此这种方法存在性能开销,它会影响对 'traited' 属性的每次访问,而不仅仅是用作左侧的那些。感谢 LeoNerd 和 ikegami 对我之前陈述的更正意见。
因此,经模块文档确认,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;
但这显然会引发错误
Can't modify non-lvalue subroutine call at Test.pm line 58, line 29
有没有办法像 lvalue subs 一样使用 Moose 访问器?
3) 使用 String traits
重新定义属性:
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
修饰符,returns 替换结果而不修改原始值,需要 Perl 5.14+。
我的选择 (2) 和 this question provide the idea to use MooseX::LvalueAttributes:
package Test;
use Moose;
use MooseX::LvalueAttribute 'lvalue';
has 'attr' => ( is => 'rw', isa => 'Str', traits => [lvalue] );
这允许使用简单的语法:
$self->attr($dummy) =~ s/pattern/string/g;
这在内部使用了 Variable::Magic and the perlsub lvalue 功能,因此这种方法存在性能开销,它会影响对 'traited' 属性的每次访问,而不仅仅是用作左侧的那些。感谢 LeoNerd 和 ikegami 对我之前陈述的更正意见。
因此,经模块文档确认,Moose 的类型检查仍然有效,并且触发了触发器。