2012-06-01 6 views

Respuesta

15

Usted no está interactuando sobre el hash, que estés interactuando sobre la lista de claves devueltas por keys, incluso antes de empezar un bucle porque

for my $key (keys %$hash_ref) { 
    ... 
} 

es aproximadamente el mismo que

my @anon = keys %$hash_ref; 
for my $key (@anon) { 
    ... 
} 

Eliminar del hash no causa ningún problema.


each, por el otro, qué repetir un hash. Cada vez que se llama, each devuelve un elemento diferente. Sin embargo, todavía es seguro para delete el elemento actual!

# Also safe 
while (my ($key) = each(%$hash_ref)) { 
    ... 
    delete $hash_ref->{$key}; 
    ... 
} 

Si se añaden o eliminan elementos de un hash al iterar sobre ella, las entradas pueden ser omitidos o duplicados - así que no hacer eso. Excepción: siempre es seguro eliminar el elemento devuelto más recientemente por cada()

+0

La frase "en la implementación actual" me asusta un poco, porque parece que hay espacio para cambiar la implementación de modo que sea ya no es seguro. Yo no confiaría en eso, pero tampoco usaría 'each()' - foreach keys está bien. – LeoNerd

+0

@LeoNerd, Perl antiguo (al menos 5.10) simplemente diga "Siempre es seguro eliminar ..." Por obvias razones de compatibilidad, dudo que esto vaya a cambiar sin introducir alguna 'característica de uso' u otro pragma similar. –

+1

que agregó que "en la implementación actual"? no siempre estaba allí, y no debería estar allí ahora, a menos que haya una muy buena razón. actualización: Parece que ya no está allí. – ysth

3

Es seguro, porque keys %hash proporciona toda la lista una vez, antes de comenzar a iterar. foreach luego continúa trabajando en esta lista pregenerada, sin importar lo que cambie dentro del hash real.

Se come tu memoria, porque mantienes toda la lista hasta que termines.

Cuestiones relacionadas