Why does Perl think that there is a nonexistent layered hash element?

Sorry, this seems like such a basic question, but I still don't get it. If I have a hash, for example:

my %md_hash = ();
$md_hash{'top'}{'primary'}{'secondary'} = 0;

How is that right?

if ($md_hash{'top'}{'foobar'}{'secondary'} == 0) {
    print "I'm true even though I'm not in that hash\n";
}

There is no "foobar" level in the hash, so should this not be false?

TIA

+5
source share
3 answers

Try searching for "Perl AutoVivitations."

The hash values ​​"spring in existence" upon first access to them. In this case, the value undef, which is equal to zero when interpreting the number.

To check for a hash value without its auto-vivifying, use the operator exists:

if (exists $md_hash{'top'}{'foobar'}{'secondary'}
    && $md_hash{'top'}{'foobar'}{'secondary'} == 0) {
    print "I exist and I am zero\n";
}

, auto-vivify $md_hash{'top'} $md_hash{'top'}{'foobar'} (.. -).

[]

tchrist , undef -. , :

if (defined $md_hash{'top'}{'foobar'}{'secondary'}
    && $md_hash{'top'}{'foobar'}{'secondary'} == 0) {
    print "I exist and I am zero\n";
}

( , undef '.)

+6

undefined . , ! ?

use warnings. ?

:

use v5.12;  # or whatever it is you are using
use strict;
use warnings;

.:)


NB: , . , , . , .

CPAN autovivification . :

use v5.10;
use strict;
use warnings;
no  autovivification;

my %md_hash = ();

$md_hash{top}{primary}{secondary} = 0;

if ($md_hash{top}{foobar}{secondary} == 0) {
    say "yup, that was zero.";
}

, :

$ perl /tmp/demo
Use of uninitialized value in numeric eq (==) at /tmp/demo line 10.
yup, that was zero.

- ==. RHS 0. LHS undef . undef 0, , LHS, RHS 0, == .

, ysth , , " - ". , , - , ==. undef 0.

autoviv, , - CPAN. , , autoviv. , , undef.

, , "" , undefined lvalue . :

$md_hash{top}{foobar}{secondary}            # implicit arrow for infix deref
$md_hash{top}->{foobar}->{secondary}        # explicit arrow for infix deref
${ ${ $md_hash{top} }{foobar} }{secondary}  # explicit prefix deref

, lvaluable undef Perl, . , autovivs.

, autoviv. autoviv - , , , . - : , autoviv. autoviv ( , : ).

, . , . Perl, . , C

 if (p && p->whatever) { ... }

, . , . Perl , - , , , , .

+7

- .

my %foo;
if ( $foo{'bar'} == 0 ) {
    print "I'm true even though I'm not in that hash\n";
}

$foo{'bar'} - undef, true 0, , , .

;

my %md_hash = ();
$md_hash{'top'}{'primary'}{'secondary'} = 0;

if ( $md_hash{'top'}{'foobar'}{'secondary'} == 0 ) {
    print "I'm true even though I'm not in that hash\n";
}

$md_hash{'top'}returns a hash link, and the foobar key is looked up in this hash. Because of {'secondary'}this, the search for the foobar element is in the context of hashing-dereferencing. This makes the $md_hash{'top'}{'foobar'}"autovivify" hash reference as the value of the "foobar" key, leaving you with this structure:

my %md_hash = (
    'top' => {
        'primary' => {
            'secondary' => 0,
        },
        'foobar' => {},
    },
);

To disable this behavior, you can use right-handed mobility. People sometimes claim that exists () affects autorecovery, but it is not.

+7
source

All Articles