2010-09-28 10 views
15

Me gustaría restablecer por completo mi %hash para que no contenga claves ni valores. Prefiero usar un delineador que tener que usar un bucle.¿Cómo puedo restablecer un hash por completo sin usar un bucle for?

Hasta aquí he intentado:

%hash = 0; 
%hash = undef; 

Pero éstas tanto generan errores en modo estricto con las advertencias está activado, por lo que escribió un simple bucle for para lograr lo mismo:

for (keys %hash) { 
    delete $hash{$_}; 
} 

Este funciona, pero realmente me gustaría hacer esto con una sola línea. ¿Hay alguna manera de simplemente restablecer un hash que estoy pasando por alto?

+9

Estoy sorprendido de que nadie tiene sin respuesta la pregunta ya. AFAICR Nunca tuve la necesidad de reiniciar un hash porque con Perl uno puede tener alcances muy ajustados. En cambio, dejo que las variables simplemente se salgan del alcance; si está en un bucle, se crearía un nuevo léxico con 'my' cerca de la parte superior. - Creo que este es un problema XY con espacio para la mejora algorítmica, tal vez dar un poco más de contexto? – daxim

+0

El hash es un global que creo cerca del comienzo de mi programa después de todos los controles y equilibrios. Se modifica con diferentes subrutinas hasta que asigno la versión final en una matriz. Dado este flujo, a menos que me falta algo, creo que es más fácil para mí 'reiniciar' este hash en particular después de asignarlo a la matriz de lo que es recrearlo con una declaración 'my'. (Es posible que esté pasando por alto un problema XY ya que no sabía cómo hacer algo como reiniciar un hash) – Structure

Respuesta

35

Ambos %hash =(); y undef %hash; funcionarán, con la diferencia de que este último devolverá algo de memoria para usar para otras cosas. El primero mantendrá la memoria de las cosas en el hash usadas anteriormente, suponiendo que se usará de nuevo más tarde de todos modos, cuando se recargue el hash.

Puede utilizar Devel::Peek observar que el comportamiento:

$ perl -MDevel::Peek -we'my %foo = (0 .. 99); %foo =(); Dump \%foo; undef %foo; Dump \%foo' 
SV = IV(0x23b18e8) at 0x23b18f0 
    REFCNT = 1 
    FLAGS = (TEMP,ROK) 
    RV = 0x23acd28 
    SV = PVHV(0x23890b0) at 0x23acd28 
    REFCNT = 2 
    FLAGS = (PADMY,SHAREKEYS) 
    ARRAY = 0x23b5d38 
    KEYS = 0 
    FILL = 0 
    MAX = 63 
    RITER = -1 
    EITER = 0x0 
SV = IV(0x23b18e8) at 0x23b18f0 
    REFCNT = 1 
    FLAGS = (TEMP,ROK) 
    RV = 0x23acd28 
    SV = PVHV(0x23890b0) at 0x23acd28 
    REFCNT = 2 
    FLAGS = (PADMY,SHAREKEYS) 
    ARRAY = 0x0 
    KEYS = 0 
    FILL = 0 
    MAX = 7 
    RITER = -1 
    EITER = 0x0 

Los MAX campos en los PVHV s son la parte importante.

+0

Gracias por la información adicional. Espero que mi hash nunca contenga los mismos valores cuando se vuelva a llenar, así que utilizaré undef% hash; sintaxis. – Structure

+11

No se trata realmente de los valores almacenados en el hash, sino de cuántos de ellos existen.Asignar, liberar y luego asignar memoria de nuevo para almacenar valores en un hash no es lo más rápido que puede hacer, por lo que perl hace la suposición de que un hash eventualmente crecerá a su tamaño original nuevamente, incluso si se borra con ' % h =() ', y mantiene la memoria requerida para almacenar tantos elementos en el hash a menos que explícitamente se le solicite que no lo haga. Esto no debe confundirse con la memoria que toman sus valores reales dentro del hash. – rafl

+0

Ahora veo la diferencia. De acuerdo, tendré que usar Devel :: Peek para ver cuál es más eficiente para mi caso de uso. – Structure

2

Uso

%hash =(); 
+2

Con 'mi' allí, en realidad está creando un nuevo hash no relacionado con el existente, sin borrar el viejo hash. – cjm

+0

ahora se corrigió – Thariama

7

¿Qué tal

%hash =(); 
5

Puede utilizar undef:

undef %hash; 
1

% hash =(); deben trabajar

0

Desde el PO pidió un chiste que funciona con el uso estricto y advertencias

delete $hash{$_} for (keys %hash) 
Cuestiones relacionadas