in reply to Should calling 'exists' create a hash key?

This is called autovivification. To me, there are two types of autovivification, the ones that are useful, and the ones that are harmful (gotcha).

I have always seen the example you gave here as the harmful type, as it goes too far to guess your purpose and 99% of the time, nobody wants that free service.

But sometime it is useful, for example:

use strict; use warnings; my $a; $a->{"a"}{"b"}{"c"} = 1;

In this case, Perl will autovivify $a->{"a"} and $a->{"a"}{"b"}, and you don't need to initialize them explicitly. This is a clever idea, if I live on the six floor of 666 on street 888, obviously both street 888 and No. 666 exist. But it is ridiculous to assume that both No. 666 and street 888 exist, just because someone has asked whether "No.666 on street 888 has a six floor".

Also in this case:

my @a; a[100] = 2;

Perl will autovivify a[0] through a[99]. a[0] through a[99] come to existance without you explicitly doing so. This is different from languages like c or Java, in which you have to explicitly do it by allocate memory/new.

There are also other types of autovivifications.

Replies are listed 'Best First'.
Re^2: Should this happen?
by Fletch (Bishop) on Sep 20, 2005 at 12:51 UTC

    Your second example with an array isn't really autovivification. Perl hashes are sparse (elements aren't stored contiguously in memory), whereas Perl arrays aren't sparse (the sequence of elements is stored contiguously in memory). When you do my %h; $h{ 100 } = 2; the one SV* is stored; when you do your example, Perl has to allocate room to store 101 SV*s and store the SV* for the 2 in the 101st (the other 100 contain pointers to sv_undef).

    Autovivification is when Perl allocates a reference to a new anonymous hash or anonymous array on the fly; this is just how arrays work. Now if you did $a[100][42] = 3.14159 that would be autovivification in that it would create a new arrayref (again, with room for 43 elements preallocated) and store it into $a[100] and then store 3.14159 into the last element.

    The difference from C or Java is that Perl will automatically extend arrays for you (which again isn't autovivification), whereas the other languages you do have to manually allocate or extend them.

      In the case of $a[100][42] = pi, obviously there is autovivification. That has no difference from $a->{"a"}{"a"} = pi.

      Whether $a[100] makes $a[0] through $a[99] autovivified is not a black white thing, and I am not the first person who classifies that as autovivification. When it is valid to look at this from a perl internal point of view as you did, it is at least not less valid to look at this from a logical point of view. Look at this:

      use strict; use warnings; my @as; $as[10] = 0; for my $a (@as) { print "."; }

      this will print 11 dots, not 1 or 12.

      To further pursuit a single correct answer to this question is not very useful, as autovivification is not a clearly defined concept, but rather a commonly used not-clearly-defined terminology that is often expressed through examples.

        Quoting perldoc perlref:

        This is one of the cases we mentioned earlier in which references could spring into existence when in an lvalue context. Before this statement, $array[$x] may have been undefined. If so, it's automatically defined with a hash reference so that we can look up "{"foo"}" in it. Likewise "$array[$x]->{"foo"}" will automatically get defined with an array reference so that we can look up "[0]" in it. This process is called autovivification.

        Going by the documentation it would seem to have a specific, clear definition: autovivification is the process of automatically creating a new reference (hashref or arrayref) to an anonymous data structure in an lvalue context. Automatically extending an array doesn't create a reference to a new anonymous data structure, it merely increases the size of an existing one.

        But yes, this is degenerating into pedantry . . . :)