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

Using $h{x} is sufficient to autovifiy a key/value pair if there is no key/value pair for the key 'x' in the hash %h.

In the first case you give, the key 'x' is added to the hash (the $h{x} bit does that) with the value undef. The %{...} then tries to dereference the undef and generates the error that you see.

The second case is equivalent to:

my $ref = undef; keys %{$ref}; # or: keys %$ref;

which, somewhat surprisingly, is fine and is about the same as asking for the keys of an empty hash. I guess this is an element of DWIM coming into play - if you ask for the keys of a hash reference that you haven't gotten around to assigning any key/value pairs to yet, then a list of not keys (and no errors generated) is a pretty reasonable thing to do.


Perl is environmentally friendly - it saves trees

Replies are listed 'Best First'.
Re^4: Keys() required to autovivify?
by Anonymous Monk on Dec 30, 2007 at 14:14 UTC
    But using $h{x} will not add an undef value into $h{x}. It just returns an undef value since $h{x} doesn't exist. I still don't see what magic keys() is using to get around the syntax error message.

      A hash can't have a key without a value (that's why I refer to key/value pairs). If you reference $h{x} in some fashion (except as a target for exists) then a x/undef pair is created (autovivified) for %h if it didn't exist already. The undef returned by $h{x} is the value associated with the key 'x'.

      "Adding" an undef value to %h when $h{x} is used is exactly what autovivification does.


      Perl is environmentally friendly - it saves trees
        Autovivification (in the case of a hash) is when a key is added to a hash where previously that key wasn't there. Just using $h{x}, as in $val = $h{x} does not add a new key to the hash. It simply assigns the default undef value to $val. Referencing through a key does autovivify the all but the last key:
        #!/usr/bin/perl my %h; my $val = $h{x}{y}; use Data::Dumper; print Dumper \%h;
        Output:
        $VAR1 = { 'x' => {} };
        Apparently, not only does $h{x} not autovivify $h{x}, but even %{$h{x}} does not autovivify $h{x} (you have to turn off strict and -w first):
        #!/usr/bin/perl my %h; %{$h{x}}; use Data::Dumper; print Dumper \%h;
        Output:
        $VAR1 = {};
        But, using keys() causes %{$h[x}} to autovivify $h{x}.
        #!/usr/bin/perl -w use strict; my %h; keys %{$h{x}}; use Data::Dumper; print Dumper \%h;
        Output:
        $VAR1 = { 'x' => {} };