in reply to keys %{$hash->{$href}} adds $href to the hash if it doesnt exist?

Hello nikmit,

it's not a case of autovivification?

It is explained in perlref and for more informations see Explaining Autovivication and Autovivification in perl and https://perlmaven.com/autovivification

On CPAN there is a pragma to disable it if unwanted.

PS exists fixes your snippet: if (exists $href->{cow} and keys %{$href->{cow}}) {  # no cow

L*

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
  • Comment on Re: keys %{$hash->{$href}} adds $href to the hash if it doesnt exist?
  • Download Code

Replies are listed 'Best First'.
Re^2: keys %{$hash->{$href}} adds $href to the hash if it doesnt exist?
by 1nickt (Canon) on Nov 17, 2017 at 13:54 UTC

    Care must be used with exists as it will indeed autovivify intermediate hashes:

    use strict; use warnings; use feature 'say'; use Data::Dumper; $Data::Dumper::Sortkeys = $Data::Dumper::Indent = 1; my $href = { cat => { milk => 1 }, dog => { bone => 1 }, }; say exists $href->{'cow'}->{'alfalfa'} ? 'cow' : 'no cow'; say Dumper $href __END__
    Output:
    no cow $VAR1 = { 'cat' => { 'milk' => 1 }, 'cow' => {}, # uh-oh 'dog' => { 'bone' => 1 } };
    So you would have to either use exists on all levels of the structure as haukex suggested:
    use strict; use warnings; use feature 'say'; use Data::Dumper; $Data::Dumper::Sortkeys = $Data::Dumper::Indent = 1; my $href = { cat => { milk => 1 }, dog => { bone => 1 }, }; say exists $href->{'cow'} && exists $href->{'cow'}->{'alfalfa'} ? 'cow' : 'no cow'; say Dumper $href __END__
    Output:
    no cow $VAR1 = { 'cat' => { 'milk' => 1 }, 'dog' => { 'bone' => 1 } };
    ... or use autovivification:
    use strict; use warnings; use feature 'say'; use Data::Dumper; $Data::Dumper::Sortkeys = $Data::Dumper::Indent = 1; my $href = { cat => { milk => 1 }, dog => { bone => 1 }, }; no autovivification; say exists $href->{'cow'}->{'alfalfa'} ? 'cow' : 'no cow'; say Dumper $href __END__
    Output:
    no cow $VAR1 = { 'cat' => { 'milk' => 1 }, 'dog' => { 'bone' => 1 } };
    Note that autovivification.pm has effect lexically:
    use strict; use warnings; use feature 'say'; use Data::Dumper; $Data::Dumper::Sortkeys = $Data::Dumper::Indent = 1; my $href = { cat => { milk => 1 }, dog => { bone => 1 }, }; { no autovivification; say exists $href->{'cow'}->{'alfalfa'} ? 'cow' : 'no cow'; say Dumper $href } say exists $href->{'cow'}->{'alfalfa'} ? 'cow' : 'still no cow'; say Dumper $href; __END__
    no cow $VAR1 = { 'cat' => { 'milk' => 1 }, 'dog' => { 'bone' => 1 } }; still no cow $VAR1 = { 'cat' => { 'milk' => 1 }, 'cow' => {}, # uh-oh 'dog' => { 'bone' => 1 } };


    The way forward always starts with a minimal test.
Re^2: keys %{$hash->{$href}} adds $href to the hash if it doesnt exist?
by nikmit (Sexton) on Nov 17, 2017 at 10:15 UTC
    Thanks - no autovivification will become a permanent presence for me, next to use strict.