in reply to Re^3: Keys() required to autovivify?
in thread Keys() required to autovivify?

Hmm. I'm not convinced. By using %{$h{x}}, I'm not saying anything different: i.e. I expect $h{x} to hold a hash, and I want it autovivified if $h{x} is undef. By using keys(%{$h{x}}), I'm saying: give me the list (or count) of keys in the hash in $h{x} and autovivify it if it's not there (returning an empty list or 0 from keys).

Replies are listed 'Best First'.
Re^5: Keys() required to autovivify?
by shmem (Chancellor) on Dec 30, 2007 at 19:03 UTC
    i.e. I expect $h{x} to hold a hash

    That's the clue - you expect that, but it isn't. You look at the box, and you are dereferencing that undef value explicitly as a hash. If you access keys/values of an undef value, your dereference happens implicitly and the hashref is created (autovivification):

    use strict; my $f; $f->{foo} = 'bar'; # okay my ($h, %new); %new = %$h; # not okay

    Said otherwise, if you dereference something, you state that it is a reference, which is different to autovivication of an undef value into something.

    Clearer?

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      To me it looks like I'm explictly dereferencing (or casting) undef in both cases. Don't you interpret %{VAL} as an explicit dereferencing of VAL?
        Of course %{VAL} is an explicit dereferencing of VAL. But assignment to a previously undefined hash reference is not.

        My previous example can be thought of and written as (and is in fact)

        use strict; my $f; ($f = {})->{foo} = 'bar'; my %new; %new = %{undef()}; # not okay

        I hope that clarifies things. Read perlref - the chapter about symbolic references. By saying %{''} you are creating a symbolic reference to the symbol table entry *{''}. Typeglobs can be empty strings, but not undef, so you cannot create a symbol reference to an undef value:

        $\ = $/; $h = ''; ${''}{foo} = 'bar'; print "\$h->{foo}: ", $h->{foo}; print "\$h: '", $h, "'"; print *{''}{HASH}; print *{$h}{HASH}; $h = undef; print *{$h}{HASH}; __END__ $h->{foo}: bar $h: '' HASH(0x885d7a4) HASH(0x885d7a4) Can't use an undefined value as a symbol reference at - line 11.

        The construct %{$h} being a symbolic reference:

        ${''}{foo} = 'bar'; $h = ''; %new = %{$h}; print "$_ => $new{$_}\n" for keys %new; __END__ foo => bar

        --shmem

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}