acadey has asked for the wisdom of the Perl Monks concerning the following question:

I just want to check if this is a viable way to clear or initialize a set of hashes: (it seems to work fine, but if it is bad practice I would like to know!)

 %_ = () for my(%hash1,%hash2,%hash3);

Thanks!

Replies are listed 'Best First'.
Re: Clear / Initialize multiple hashes
by BrowserUk (Patriarch) on Sep 19, 2013 at 18:05 UTC
    I just want to check if this is a viable way to clear or initialize a set of hashes:

    No. Your code does nothing.

    This bit: %_ = () would assign nothing to the hash %_; which is probably empty anyway.

    But that code is never invoked because this bit: for  my(%hash1,%hash2,%hash3); doesn't result in anything, so the for never iterates.

    The overall effect of you code is exactly the same as just: my(%hash1,%hash2,%hash3);

    And the only reason "it seems to work fine"; is because it is not necessary to clear or initialise variables when you declare them.

    Any variable declared with my, is a new clean, empty variable. You don't need to do anything to it to make it so.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Clear / Initialize multiple hashes
by choroba (Cardinal) on Sep 19, 2013 at 18:09 UTC
    Not exactly. By using my, you declare new hashes. If you used warnings, Perl would tell you:
    "my" variable %hash1 masks earlier declaration in same scope

    So, the statement is equivalent to

    my (%hash1, %hash2, %hash3);

    Note that the hash %_ is not cleared, because the body of the loop is not run (the brand new hashes are emtpy).

    Without my, %_ would be cleared, but %hash1 and company would stay untouched. To test, just play with comments in the following code:

    # use strict; use warnings; %_ = (u => 2); %hash1 = (b => 3); # %hash1 = (b => 3); # %_ = () for my (%hash1,%hash2,%hash3); # %_ = () for (%hash1,%hash2,%hash3); print %_, %hash1, "\n";

    To clear a hash, use undef or %hash = ().

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Thanks! both replies helped a lot. I thought it looked a little funky and thought I would check so I am really glad I did. Any suggestion on the best way to clear all of them? At initialization I can just do:

      my(%hash1,%hash2,%hash3);

      but later on if I want to clear all of them how should I go about it? I mean I could just clear each one individually, but when I have a long list that can be a bit of a pain...

        but later on if I want to clear all of them how should I go about it?

        The simplest way is to scope them such that they get reinitialised by re-entering the scope each time you want to re-use them:

        for( some loop condition or contruct ) { my( %hash1, %hash2, %hash3 ); ## do stuff with them ... }

        Each time that loop iterates, the hashes will be reinitialised for you.

        But, it you really need to do it manually, you could use:

        undef %$_ for \(%h1,%h2,%h3);

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        You can do
        ( %hash1, %hash2, %hash3 ) = (); # or %hash1 = %hash2 = %hash3 = ();
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Clear / Initialize multiple hashes
by AnomalousMonk (Archbishop) on Sep 20, 2013 at 13:25 UTC

    If you have a bunch of hashes (could also be a bunch of arrays) that you need to define en masse and identically initialize as non-empty, something like this works:

    >perl -wMstrict -MData::Dump -le "use constant HASH => qw(foo bar 1 one); ;; %$_ = HASH for \my (%hash1, %hash2); dd \%hash1; dd \%hash2; " { 1 => "one", foo => "bar" } { 1 => "one", foo => "bar" }
Re: Clear / Initialize multiple hashes
by hdb (Monsignor) on Sep 20, 2013 at 06:25 UTC

    If you really have a long list of hashes, you could store them as an array or hash of hash references. In which case you can clear them using a loop or even clear the array or hash that contains them.