in reply to Re^3: Why does exists cause autovivication?
in thread Why does exists cause autovivication?

Even the Perl people call autovivication - specifically when using exists - surprising behaviour:

exists

Near the bottom:
"This surprising autovivification in what does not at first--or even second--glance appear to be an lvalue context may be fixed in a future release."

I would not expect something that just returns true or false to modify the data that is passed to it. I know that people are going to say that it is not modifying the data passed to it - because you are actually dereferencing the hash elements in the CALL to exists() - not within exists itself. However, there must be some way to prevent it from happening when calling exists(). If any one of the lower hash keys does not exist in the hash being tested, then obviously the one you're testing for does not, and exists() should just return false.

  • Comment on Re^4: Why does exists cause autovivication?

Replies are listed 'Best First'.
Re^5: Why does exists cause autovivication?
by 1nickt (Canon) on Jul 19, 2017 at 21:21 UTC

    It's not that hard.

    Either, instead of exists, use Data::Diver (by tye):

    $ perl -Mstrict -MData::Diver=Dive -MData::Dumper -wE ' my $h; $h->{foo}->{bar}->{baz} = "qux"; say Dumper $h; say Dive( $h, qw/ foo bar baz / ) ? 1 : 0; say Dive( $h, qw/ foo NOT baz / ) ? 1 : 0; say Dumper $h; ' $VAR1 = { 'foo' => { 'bar' => { 'baz' => 'qux' } } }; 1 0 $VAR1 = { 'foo' => { 'bar' => { 'baz' => 'qux' } } };

    Or, if you want to use exists, just test for each level that you are not sure exists before going any deeper:

    $ perl -Mstrict -MData::Dumper -wE ' my $h; $h->{foo}->{bar}->{baz} = "qux"; say Dumper $h; say( (exists $h->{foo}->{bar}->{baz}) ? 1 : 0 ); say( (exists $h->{foo}->{NOT} && exists $h->{foo}->{NOT}->{baz}) ? 1 : + 0 ); say Dumper $h; ' $VAR1 = { 'foo' => { 'bar' => { 'baz' => 'qux' } } }; 1 0 $VAR1 = { 'foo' => { 'bar' => { 'baz' => 'qux' } } };


    The way forward always starts with a minimal test.