Chon-Ji has asked for the wisdom of the Perl Monks concerning the following question:

Am I correct to assume that there is no need to intialize a hash element to 0 or 1, when my purpose is just to increment it? I tried these two codes, and both of them seem to have produced the same result. Because of this I thought that if a hash element has no value and it is used on an arithmetic operation then its default value is zero. Am I correct? code1
if(exists $myhash{$key}) { $myhash{$key} = $myhash{$key} + 1; } else { $myhash{$key} = 1; }
code2
$myhash{$key} = $myhash{$key} + 1;

Replies are listed 'Best First'.
Re: Initialization of hash element....
by GrandFather (Saint) on Jun 01, 2007 at 02:34 UTC

    Yes, undef gets treated as 0. Actually you can use += to make it even more succinct:

    $myhash{$key} += 1;

    DWIM is Perl's answer to Gödel
Re: Initialization of hash element....
by Herkum (Parson) on Jun 01, 2007 at 03:07 UTC

    Perl will attempts to do what it thinks were you trying to accomplish.

    • In other words, if you add to 1 to a string, it will treat the hash element as a digit.
    • If you try to concatenate a string it would treat your hash element as a string.

    It tends to throw people who are used to programming with Java or C#.

Re: Initialization of hash element....
by blazar (Canon) on Jun 01, 2007 at 11:58 UTC
    Because of this I thought that if a hash element has no value and it is used on an arithmetic operation then its default value is zero. Am I correct?

    Yes, and this has not strictly to do with hash elements, but with any variable, be it a simple scalar or an element of an aggregate. One caveat though: under warnings, you will get a warning if you use such a value in a generic expression, but you won't if you use mutators instead:

    tilde:~ [13:53:30]$ perl -we '$a=$a+1' Use of uninitialized value in addition (+) at -e line 1. tilde:~ [13:53:50]$ perl -we '$a+=1' Name "main::a" used only once: possible typo at -e line 1. tilde:~ [13:53:58]$ perl -we '$a++' Name "main::a" used only once: possible typo at -e line 1.
      $ perl -we '$a*=0' Name "main::a" used only once: possible typo at -e line 1. Use of uninitialized value in multiplication (*) at -e line 1.
      Only certain mutators suppress the warning - those that most make sense with a 0 / "" default. These are:

      ++ and -- (either pre or post), +=, -=, .=, |=, ^=, &&=, ||=.

      But last I checked, some of those erroneously warn when used on a tied variable.