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

Why does using $# define a previously undefined variable?
#!/usr/bin/perl $array=undef; warn "array ",defined($array) ? 'is' : 'is not'," defined"; warn '$#{$array} is ',$#{$array}; warn "array ",defined($array) ? 'is' : 'is not'," defined";
Produces this:
array is not defined at /home/smitty/bat/t line 3. $#{$array} is -1 at /home/smitty/bat/t line 4. array is defined at /home/smitty/bat/t line 5.

Replies are listed 'Best First'.
Re: Using $# defines a variable?
by haukex (Archbishop) on May 18, 2019 at 21:27 UTC

    Short answer: autovivification.

    When you write $#{$array}, you're asking Perl what the last index of the array is which the reference $array points to, in other words, you're using the previously undefined $array like an array reference, so Perl autovivifies an anonymous array for you. See also item 3 under Using References.

    use warnings; use strict; use Data::Dumper; my $array; print Dumper($array); print Dumper($#{$array}); print Dumper($array); __END__ $VAR1 = undef; $VAR1 = -1; $VAR1 = [];
      Additionally it's worth noting that $#name is an lvalue allowing to resize the array @name

      DB<2> @a=1..10 DB<3> $#a = 3 DB<4> x @a 0 1 1 2 2 3 3 4

      In other words autovivification is necessary to allow this feature.

      Lvalues can be passed around, Perl can't be sure if it's only used for a read access.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Re: Using $# defines a variable?
by Athanasius (Archbishop) on May 19, 2019 at 03:33 UTC

    Hello smittypaddler,

    Some notes:

    1. Obligatory reference on autovivification: Autovivification: What is it and why do I care? by Uri Guttman
    2. $#{$array} can be written more simply without the braces: $#$array
    3. The CPAN module autovivification can be used to disable this behaviour:
      use strict; use warnings; no autovivification; my $array; warn sprintf 'array is%s defined', defined $array ? '' : ' not'; warn '$#$array is ', $#$array; warn sprintf 'array is%s defined', defined $array ? '' : ' not';

      Output:

      13:28 >perl 1999_SoPW.pl array is not defined at 1999_SoPW.pl line 7. Can't use an undefined value as an ARRAY reference at 1999_SoPW.pl lin +e 8. 13:28 >

    Hope that’s of interest,

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