tags:

views:

194

answers:

6

I would like to completely reset my %hash so that it does not contain keys or values at all. I prefer to use a one-liner than have to use a loop.

So far I have tried:

%hash = 0;
%hash = undef;

But these both throw errors in strict mode with warnings enabled, so I wrote a simple for loop to achieve the same thing:

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

This works but I would really like to do this with a one-liner. Is there a way to simply reset a hash that I am overlooking?

+2  A: 

Use

%hash = ();
Thariama
With `my` there, you're actually creating a new hash unrelated to the existing one, not clearing out the old hash.
cjm
it is now corrected
Thariama
+6  A: 

How about

%hash = ();
Thilo
+2  A: 

You can do:

%hash = ();
codaddict
+4  A: 

You can use undef:

undef %hash;
eugene y
+23  A: 

Both %hash = (); and undef %hash; will work, with the difference that the latter will give back some memory to use for other things. The former will keep the memory the things in the hash used before, assuming it'll be used again later anyway, when the hash is being refilled.

You can use Devel::Peek to observe that behaviour:

$ 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

The MAX fields in the PVHVs are the important bit.

rafl
Thanks for the additional insight. I expect that my hash will never contain the same values when it is re-populated so I will utilize the undef %hash; syntax.
Structure
It's not really about what values are stored in the hash, but about how many of them there are. Allocating, freeing, and then allocating some memory again to store values in a hash isn't the fastest thing you can do, so perl makes the assumption that a hash will eventually grow to its original size again, even if it is cleared with `%h = ()`, and keeps the memory required to store as many elements around in the hash unless explicitly asked not to do so. This is not to be confused with the memory your actual values within the hash take up.
rafl
Now I see the difference. Alright, I will have to use Devel::Peek to see which is more efficient for my use case.
Structure
Actually, Devel::Peek is not what tells you what's more efficient. That's what your brain is for. If you are clearing a hash that had 65 members and are just going to put 65 members in, then you might as well just reuse the memory. If you are clearing a hash that had over 9000 entries in it, and just want to have three, then sure... time to clear it.
jrockway
+1  A: 

%hash = (); must work

Pramodh