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

only if $h{x} (was a hash and) had at least one element

Then test whether the value of $h{x} actually is a hash reference.

If you say keys %{$h{x}} it is assumed you know what you are doing and want autovivifying, while dereferencing an undef value could just be a mistake. strict 'refs' catches that - that is what strict is about ;-)

By using keys you look inside the box (= the hashref), so perl autovivifies it, if it doesn't exist; by dereferencing you look at the box only.

--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}

Replies are listed 'Best First'.
Re^4: Keys() required to autovivify?
by Anonymous Monk on Dec 30, 2007 at 14:12 UTC
    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).
      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?