2010-09-28 5 views
15

Je voudrais complètement réinitialiser mon %hash afin qu'il ne contienne pas de clés ou de valeurs du tout. Je préfère utiliser un one-liner que d'utiliser une boucle.Comment réinitialiser complètement un hachage sans utiliser de boucle for?

Jusqu'à présent, j'ai essayé:

%hash = 0; 
%hash = undef; 

Mais ces deux lancer des erreurs en mode strict avec des avertissements est activé, j'ai donc écrit une simple boucle pour obtenir la même chose:

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

Cette fonctionne mais je voudrais vraiment le faire avec un one-liner. Y at-il un moyen de réinitialiser un hachage que je néglige?

+9

Je suis étonné que personne a déjà la question non posée. AFAICR Je n'ai jamais eu besoin de réinitialiser un hachage car avec Perl on peut avoir des portées très serrées. Je laisse plutôt les variables tomber tout simplement hors de la portée; si dans une boucle, un nouveau lexique serait créé avec 'my' près du sommet. - Je pense que c'est un problème XY avec de la place pour l'amélioration algorithmique, peut-être donner plus de contexte? – daxim

+0

Le hachage est un global que je crée au début de mon programme après tous les freins et contrepoids. Il est modifié avec différents sous-programmes jusqu'à ce que j'attribue la version finale dans un tableau. Étant donné ce flux, à moins que je ne manque quelque chose, je crois qu'il est plus facile pour moi de 'réinitialiser' ce hachage particulier après l'avoir assigné au tableau que de le recréer avec une instruction 'my'. (Il est possible que je néglige un problème XY puisque je ne savais pas comment faire quelque chose comme réinitialiser un hachage) – Structure

Répondre

35

Les deux %hash =(); et undef %hash; fonctionneront, à la différence que ce dernier va redonner de la mémoire à utiliser pour d'autres choses. Le premier gardera la mémoire les choses dans le hachage utilisé auparavant, en supposant qu'il sera utilisé à nouveau plus tard de toute façon, quand le hachage est en train d'être rempli.

Vous pouvez utiliser Devel::Peek pour observer ce comportement:

$ 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 

Les champs MAX dans les PVHV s sont peu importants.

+0

Merci pour la perspicacité supplémentaire. Je m'attends à ce que mon hachage ne contienne jamais les mêmes valeurs quand il est re-peuplé donc j'utiliserai le hash undef%; syntaxe. – Structure

+11

Il ne s'agit pas vraiment de savoir quelles sont les valeurs stockées dans le hachage, mais de connaître le nombre d'entre elles.Allouer, libérer, puis allouer de nouveau de la mémoire pour stocker des valeurs dans un hachage n'est pas ce que vous pouvez faire de plus rapide, donc perl fait l'hypothèse qu'un hachage repassera à sa taille d'origine, même s'il est effacé avec ' % h =() ', et conserve la mémoire nécessaire pour stocker autant d'éléments dans le hachage, sauf demande explicite de ne pas le faire. Cela ne doit pas être confondu avec la mémoire que prennent vos valeurs réelles dans le hachage. – rafl

+0

Maintenant, je vois la différence. D'accord, je vais devoir utiliser Devel :: Peek pour voir ce qui est le plus efficace pour mon cas d'utilisation. – Structure

2

Utilisez

%hash =(); 
+2

Avec 'my' là, vous êtes en train de créer un nouveau hachage sans rapport avec l'existant, ne pas effacer le vieux hash. – cjm

+0

il est maintenant corrigé – Thariama

7

Que diriez-vous

%hash =(); 
5

Vous pouvez utiliser undef:

undef %hash; 
1

% haché =(); doit travailler

0

Depuis l'OP a demandé une doublure qui fonctionne avec une utilisation stricte et avertissements

delete $hash{$_} for (keys %hash) 
Questions connexes