我在某些来源中看到这一行代码
( $self->{arg} ) = ( ( delete $self->{arg} ) =~ /(.*)/s ) if ${^TAINT};
我明白不了了我也知道delete
我的问题是,在什么情况下有必要或首选使用删除,而不够简单
( $self->{arg} ) = ( ( $self->{arg} ) =~ /(.*)/s ) if ${^TAINT};
例如
#!/usr/bin/env perl -T use 5.014; use warnings; package Some { use Moose; has 'arg' => (is => 'rw',isa => 'Str'); sub doit { my $self = shift; #( $self->{arg} ) = ( ( delete $self->{arg} ) =~ /(.*)/s ) if ${^TAINT}; ( $self->{arg} ) = ( ( $self->{arg} ) =~ /(.*)/s ) if ${^TAINT}; } }; my $some = Some->new( arg => 'some text' ); $some->doit(); say $some->arg;
解决方法
使用正常的哈希删除值并重新插入将给出与修改相同的结果.
commit没有提供任何关于为什么他删除它的信息,只是他复制了Mason 1的功能.但如果你看看HTML::Mason::Lexer的来源,你会发现这个评论:
We need to untaint the component or else the regexes will fail
to a Perl bug. The delete is important because we need to
create an entirely new scalar,not just modify the existing one.
($current->{comp_source}) = (delete $current->{comp_source}) =~ /(.*)/s if taint_is_on;
所以这样做的原因是有一个新的标量,虽然他不这样做的另一个地方,他是不成功的:Mason::Interp,所以我的猜测是一个更早的Perl错误,当挽救.
所以不同的是,删除会给你一个新的标量,虽然这很少有一个实际的应用. (当然,删除和插入也是一个较慢的操作.)
use strict; my $hash->{test} = 'test'; print \($hash->{test}),"\n"; ( $hash->{test} ) = ( ( $hash->{test} ) =~ /(.*)/s ); print \($hash->{test}),"\n"; ( $hash->{test} ) = ( ( delete $hash->{test} ) =~ /(.*)/s ); print \($hash->{test}),"\n";
给
SCALAR(0x7f84d10047e8) SCALAR(0x7f84d10047e8) SCALAR(0x7f84d1029230)