2015-11-15 1 views
12

j'ai vu cette ligne de code dans certaines sourcesblanchissez un membre de hachage béni avec ou sans la suppression

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

Je comprends la blanchissez. J'ai aussi connu delete

Ma question est, dans quelles circonstances est-il nécessaire ou préférable d'utiliser le delete, et ne l'est pas assez pour utiliser le plus simple

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

Par exemple

#!/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

Je suis d'accord avec vous. Modifier la valeur de hachage en place (ou, dans ce cas, la laisser inchangée) semble équivaloir à la supprimer et à la réinsérer. Pouvez-vous dire où vous avez vu cette pratique? – Borodin

+0

@Borodin Je l'ai vu https://metacpan.org/source/JSWARTZ/Mason-2.24/lib/Mason/Compilation.pm#L105 – Nemo

+1

Cela peut faire la différence dans le cas de tie() s, mais je ne vois rien ici . Dunno. Je ne penserais jamais à faire ça. –

Répondre

3

Avec un hachage normal supprimant la valeur et réinsérant donnera le même résultat que de le modifier en place.

Le commit ne donne aucune information sur la raison pour laquelle il supprime simplement qu'il copie la fonctionnalité de Mason 1. Mais si vous regardez la source de HTML::Mason::Lexer, vous trouverez ce commentaire:

Nous avons besoin pour dénouer le composant, sinon les expressions régulières échoueront à un bogue Perl. La suppression est importante car nous devons créer un scalaire entièrement nouveau, pas seulement modifier celui existant.

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

donc la raison de le faire de cette façon est d'avoir un nouveau scalaire, bien qu'il ne le fait pas pour l'autre endroit où il est blanchissez: Mason::Interp, donc je suppose un bug Perl plus tôt, quand il n'est pas taché.

Donc, la différence est que delete vous donnera un nouveau scalaire, même si cela aura rarement une application pratique. (Supprimer et insert est également une opération plus lente, bien sûr.)

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"; 

donne

SCALAR(0x7f84d10047e8) 
SCALAR(0x7f84d10047e8) 
SCALAR(0x7f84d1029230)