http://www.perlmonks.org?node_id=1070109

rammohan has asked for the wisdom of the Perl Monks concerning the following question:

what is the use of autovivification in perl? i know we are using this for dynamical data structure .. i studied about autovivification but i couldn't understood this. this is my examples,
print "autovivification in perl using Array:\n"; my @quick = (); $quick[0][3] = "perl"; print Dumper @quick; print "autovivification in perl using scalar"; my $ref; $ref->{Oxford}->['Ram']->{Population} = 500000; print Dumper $ref; print "autovivification in perl using hash"; my %hash = (); $hash{ram}->{mohan}->{perl}->{linux}= "Larry_Wall"; print Dumper %hash;
it showing result fine.when we use this autovivification in perl.Please let us know

Replies are listed 'Best First'.
Re: Autovivification in perl
by choroba (Cardinal) on Jan 10, 2014 at 12:42 UTC
    It makes it possible to write
    push @{ $at_line{$string} }, $line_number;

    instead of

    $at_line{$string} = [] unless exists $at_line{$string}; push @{ $at_line{$string} }, $line_number;
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      Well,
      push @{ $at_line{$string} //= [] }, $line_number;
      or even
      push @{ $at_line{$string} ||= [] }, $line_number;
      would do.
Re: Autovivification in perl
by 2teez (Vicar) on Jan 10, 2014 at 13:29 UTC
Re: Autovivification in perl
by marto (Cardinal) on Jan 10, 2014 at 12:39 UTC
Re: Autovivification in perl (less clicks of the keyboard to create arbitrarily complex data structures)
by Anonymous Monk on Jan 10, 2014 at 13:47 UTC
Re: Autovivification in perl
by Athanasius (Archbishop) on Jan 10, 2014 at 14:59 UTC

    As mentioned by Anonymous Monk above, has an autovivification module for those (rare) occasions when you don’t want it to occur:

    #! perl use strict; use warnings; print "\nWITH autovivification:\n"; my $hashref1; printf "1. \$hashref1 %s defined\n", (defined $hashref1 ? 'IS' : 'is N +OT'); my $foo = $hashref1->{bar}; printf "2. \$hashref1 %s defined\n", (defined $hashref1 ? 'IS' : 'is N +OT'); no autovivification; print "\nWITHOUT autovivification:\n"; my $hashref2; printf "3. \$hashref2 %s defined\n", (defined $hashref2 ? 'IS' : 'is N +OT'); my $baz = $hashref2->{bar}; printf "4. \$hashref2 %s defined\n", (defined $hashref2 ? 'IS' : 'is N +OT');

    Output:

    0:43 >perl 830_SoPW.pl WITH autovivification: 1. $hashref1 is NOT defined 2. $hashref1 IS defined WITHOUT autovivification: 3. $hashref2 is NOT defined 4. $hashref2 is NOT defined 0:43 >

    This may (occasionally) be a handy tool to have in the toolbox.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Autovivification in perl
by ikegami (Patriarch) on Jan 10, 2014 at 20:24 UTC

    Without autovivification,

    $quick[0][3] $ref->{Oxford}{Ram}{Population} $hash{ram}{mohan}{perl}{linux}

    would have to be written as follows:

    ( $quick[0] //= [] )->[3] ((( $ref //= {} )->{Oxford} //= {} )->{Ram} //= {} )->{Population} ((( $hash{ram} //= {} )->{mohan} //= {} )->{perl} //= {} )->{linux}

    Which do you prefer?

Re: Autovivification in perl
by LanX (Saint) on Jan 10, 2014 at 12:39 UTC
    Plz show some efforts!

    There are excellent discussions easily searched or googled, no need to restart those from scratch cause you are too lazy.

    After reading them you may wanna ask more specific questions.

    Keep in mind you can still join old discussions.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

Re: Autovivification in perl
by pemungkah (Priest) on Jan 11, 2014 at 00:17 UTC
    "Autivivification" is a fancy word for "don't let me mess up if stuff isn't there yet".

    In hashes, autovivification creates the hash entry you were looking for and sets it to undef; if you try to continue down a chain of references to other anonymous data structures, autovivification creates them (empty) and continues.

    So If you said

    $pinky = {}; $pinky->{zorch}{poit}{narf} = "I don't know, Brain, where will we get +hip-waders this time of night?";
    what logically happens is this:
    $pinky = {}; # Ooh, you referenced zorch, and it's not there. $pinky->{zorch} = undef; # And now you want to reference 'poit' in that as a hash, so we'll add + an new anonymous hash instead: $pinky->{zorch} = {}; $pinky->{zorch}{poit} = undef; # and then you want to go one more level: $pinky->{zorch}{poit} = {}; $pinky->{zorch}{poit}{narf} = undef; # And you want to set that to a value: $pinky->{zorch}{poit}{narf} = "I don't know, Brain, where will we get +hip-waders this time of night?";
    Note that Perl does not actually keep doing and undoing the assignments of undef; it just plows through, building the structures as it goes. That's autovivification. Note that if you just access something at the end of one of these chains, you'll get undef; Perl does set the value to undef if you don't assign it anything, just as it would if you referenced a key in a hash that hadn't been set yet.

    Also note that this

    $eat_memory={}; $eat_memory->{bad_idea}[99999][99999][99999] = "yummy, yummy, memory";
    forces autovivification to create all those unused entries in the arrays, so we have 'bad_idea' referencing a 100,000 element anonymous array, the last element of which references a 100,000 element anonymous array, the last element of which references another 100,000 element array, the last element of which is set to our string. Using hashes unless you absolutely have to use arrays will let you simulate a sparse array.