Опоздание благословенного хеш-члена с удалением или без него

Я видел эту строку кода в некоторых источниках

( $self->{arg} ) = ( ( delete $self->{arg} ) =~ /(.*)/s ) if ${^TAINT}; 

Я понимаю, что не могу. Я также знал delete

Мой вопрос в том, в каких обстоятельствах это необходимо или предпочтительнее использовать 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;

Ответ 1

При нормальном хеше, удаляющем значение и повторное вставку, вы получите тот же результат, что и его модификация.

commit не дает никакой информации о том, почему он удаляет его только для того, чтобы он копировал функциональность от Mason 1. Но если вы посмотрите в источнике HTML:: Mason:: Lexer вы найдете этот комментарий:

Нам нужно отключить компонент, иначе регексы не сработают к ошибке Perl. Удаление важно, потому что нам нужно создайте совершенно новый скаляр, а не просто измените существующий.

($current->{comp_source}) = (delete $current->{comp_source}) =~ /(.*)/s if taint_is_on;

Таким образом, причина этого заключается в том, чтобы иметь новый скаляр, хотя он не делает этого для другого места, где он не может: Мейсон:: Interp, поэтому моя догадка - это более ранняя ошибка Perl, когда она не используется.

Таким образом, разница в том, что с delete даст вам новый скаляр, хотя это редко будет иметь практическое применение. (Разумеется, удаление и вставка также более медленная.)

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)