in reply to push undefined and vivification

why perl vivify an anonymous array in @a?

Cos that's what you asked it to do :)

push @{$a[0]}, "foo"; say's treat the value in $a[0] as a reference to an array, and then push 'foo', onto the array located at that reference @{ <array_reference> }.

If the value of $a[ 0 ] is undefined, perl autovivifies an anonymous array, stores a reference to it in $a[ 0 ] and then pushes 'foo' into that.

Perl will only autovivify the anon. array if the value of the array element is undefined. if it has any value that would test as defined, including '' & 0, it will issue a warning.

W:\current>perl use strict; use Data::Dumper; my @a = ( 'fred' ); push @{ $a[ 0 ] }, 'foo'; print Dumper \@a; ^Z Can't use string ("fred") as an ARRAY ref while "strict refs" in use a +t - line 4. W:\current>perl use strict; use Data::Dumper; my @a = ( '' ); push @{ $a[ 0 ] }, 'foo'; print Dumper \@a; ^Z Can't use string ("") as an ARRAY ref while "strict refs" in use at - +line 4.

Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
Timing (and a little luck) are everything!

Replies are listed 'Best First'.
Re: Re: push undefined and vivification
by edan (Curate) on Jan 18, 2004 at 06:02 UTC

    Perl will only autovivify the anon. array if the value of the array element is undefined. if it has any value that would test as defined, including '' & 0, it will issue a warning.

    Actually, perl will die, not issue a warning:

    Can't use string (""%s"") as %s ref while ""strict refs"" in use

    (F) Only hard references are allowed by "strict refs". Symbolic references are disallowed. See the perlref manpage. - perldiag

    That (F) means A fatal error (trappable), i.e. die.

    Programmer beware.

    --
    3dan

Re: Re: push undefined and vivification
by oha (Friar) on Jan 18, 2004 at 12:07 UTC
    in use strict it's right. but without, the code:
    use Data::Dumper; @a=('bar'); print Dumper(\@a); push @{$a[0]}, "foo"; print Dumper(\@a); print Dumper(\@bar);
    actually append 'foo' to @bar:
    $VAR1 = [ 'bar' ]; $VAR1 = [ 'bar' ]; $VAR1 = [ 'foo' ];

    in that case, so, perl do one of three things:

  • append to the array named by the value of $a[0], or
  • append to the array-ref in $a[0], or
  • create an anonymous array and put the reference in $a[0]
    in use strict; the behavior of push is predictable, but without -- and using a string in $a[0] -- the behavior is not predictable.

    this may be a good reason to use strict, without perl may use the @{$something} as array-ref or variable name... a bit confusing, doesn't it?

      in use strict; the behavior of push is predictable, but without -- and using a string in $a[0] -- the behavior is not predictable
      Wrong. The behaviour is perfectly predictable. Observe
      use Data::Dumper; @a = 'bar'; @bar = 6; warn push @{$a[0]}, 7; warn Dumper( \@a, \@bar ); warn push @{"$a[0]"}, 8; warn Dumper( \@a, \@bar ); warn push @{"bar"}, 9; warn Dumper( \@a, \@bar ); undef $a[0]; warn push @{$a[0]}, 11; warn Dumper( \@a, \@bar ); __END__ 2 at - line 4. $VAR1 = [ 'bar' ]; $VAR2 = [ 6, 7 ]; 3 at - line 7. $VAR1 = [ 'bar' ]; $VAR2 = [ 6, 7, 8 ]; 4 at - line 10. $VAR1 = [ 'bar' ]; $VAR2 = [ 6, 7, 8, 9 ]; 1 at - line 13. $VAR1 = [ [ 11 ] ]; $VAR2 = [ 6, 7, 8, 9 ];

      without perl may use the @{$something} as array-ref or variable name... a bit confusing, doesn't it?
      Why? Observe
      @a = 'bar'; @bar = 6; warn 'PUSHING ONTO @BAR' if defined $a[0]; push @{$a[0]}, 'bar'; undef $a[0]; warn 'PUSHING ONTO $a[0]' if not defined $a[0]; push @{$a[0]}, 'bar'; use Data::Dumper; warn Dumper( \@a, \@bar ); __END__ PUSHING ONTO @BAR at - line 4. PUSHING ONTO $a[0] at - line 10. $VAR1 = [ [ 'bar' ] ]; $VAR2 = [ 6, 'bar' ];