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

Hi Monks, I've been confused today by the following phenomenon:
script 1 foreach (qw/a b c d/){$hash{$_}++}; print keys %hash, "\n"; print keys %{$hash{'wrong'}}; print keys %hash, "\n"; OUTPUT: cabd cwrongabd --------------------------------- script 2 foreach (qw/a b c d/){$hash{$_}++}; print keys %hash, "\n"; print $hash{'wrong'}; print keys %hash, "\n"; OUTPUT: cabd cabd
why does the third line in the first script seemingly cause the key 'wrong' to magically appear in the hash, whereas the corresponding line in the second script doesn't? A brief reading of perlfunc:keys doesn't seem to give me an answer, so I guess there must be a deeper reason. Can anyone enlighten me?

Replies are listed 'Best First'.
Re: puzzling behaviour of keys function
by duff (Parson) on Dec 08, 2004 at 15:04 UTC

    Autovivification. It's not the third line that causes the key to appear in the hash, but the second. The keys function is just letting you know that it's there.

Re: puzzling behaviour of keys function
by ikegami (Patriarch) on Dec 08, 2004 at 15:43 UTC

    %{$hash{'wrong'}}; implies $hash{'wrong'} is a hash ref. Since $hash{'wrong'} is not defined, perl creates an anonymous hash for you and places a reference to it in $hash{'wrong'}. This is called Autovivification.

    To avoid it here, do
    print($hash{'wrong'} ? () : keys(%{$hash{'wrong'}}), "\n");
    or
    print(keys(%{$hash{'wrong'}}), "\n") if $hash{'wrong'};
    depending if you want a blank line or no line at all.

Re: puzzling behaviour of keys function
by dragonchild (Archbishop) on Dec 08, 2004 at 15:00 UTC
    Try using Data::Dumper instead of print() and you'll see the reason.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: puzzling behaviour of keys function
by Anonymous Monk on Dec 08, 2004 at 15:15 UTC
    Thanks for the very rapid replies. Ok, so using Data::Dumper in line 4 of script 2 gives
    OUTPUT: $VAR1 = { 'c' => 1, 'wrong' => {}, 'a' => 1, 'b' => 1, 'd' => 1 };
    So.. print keys %{$hash{'wrong'}} causes an element to be added to %hash, the key is 'wrong' and the value is a reference to an empty, anonymous hash. Have I got that correct?
      Yep.