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

Is the following ok ? If not, how should the array be initalized ? I expected 0,4,5,6,7,8,9 to be defined and exist but have no value..
#!/app/geneva/perl/bin/perl @x = (); $x[10] = 1; @x[1..3] = 1; for($y=0; $y!=@x; $y++) { if(exists($x[$y])) { print "$y exists"; } if(defined($x[$y])) { print "\t$y defined"; } print "\n"; } Gives the following output: 1 exists 1 defined 2 exists 3 exists 10 exists 10 defined

Replies are listed 'Best First'.
Re: Initialization of arrays
by chester (Hermit) on Sep 22, 2005 at 13:39 UTC
    @x[1..3] = 1;

    The left is an array slice; it's expecting a list on the right. The "list" you gave it is essentially like (1, undef, undef). So only $x[1] is getting a value here. You could write it like:

    @x[1..3] = (1,1,1)

    For this:

    for($y=0; $y!=@x; $y++)

    You should generally avoid the C-style for. You can rewrite it like this:

    for my $y (0..$#x)

    Also to easily view the contents of your array without having to loop, you may look into Data::Dumper.

    edit: Fixed as per [id://ikegami]'s reply

      You can rewrite it like this:
      for my $y (0..@x)

      You mean:
      for my $y (0..$#x)

        For times when I access the last element of an array, I use @array[-1]; however, when I need to know the value of the last index, such as in a loop above, I have seen people recommend two approaches. Let's use the for snippet from the above -- it could be written in either of:

        for my $y (0..@x-1) { } # or # for my $y (0..$#x) { }

        Is there a practical difference?

        <-radiant.matrix->
        Larry Wall is Yoda: there is no try{} (ok, except in Perl6; way to ruin a joke, Larry! ;P)
        The Code that can be seen is not the true Code
        "In any sufficiently large group of people, most are idiots" - Kaa's Law
Re: Initialization of arrays
by ikegami (Patriarch) on Sep 22, 2005 at 14:07 UTC
    I expected 0,4,5,6,7,8,9 to be defined ... but have no value.

    That will never happened, because defined means "has a value". (Well, that's assuming "undefined" is not considered a value. defined will obviously return false when the value is undef.)

Re: Initialization of arrays
by svenXY (Deacon) on Sep 22, 2005 at 13:46 UTC
    Hi,
    in addition: as long as you don't assign something (even undef) to an index, the array element does not exist.
    #!/usr/bin/perl use strict; use warnings; my @x = (); $x[10] = 1; @x[1..3] = (1,1); $x[5] = undef; for(my $y=0; $y!=@x; $y++) { if(exists($x[$y])) { print "$y exists"; } if(defined($x[$y])) { print "\t$y defined"; } print "\n"; } prints: 1 exists 1 defined 2 exists 2 defined 3 exists 5 exists 10 exists 10 defined
    Although the value is not defined (undef), it still exists.
    Regards,
    svenXY
Re: Initialization of arrays
by sk (Curate) on Sep 22, 2005 at 14:02 UTC
    chester and svenXY have told you why it does not do what you want and how you can init the slice. Here is a quick way to init if you want to do it for a large number of indices.

    use strict; use warnings; use Data::Dumper; my @x; @x[0..3] = map {1}0..3; # this map returns a list of 1's (4 elements) print Dumper(\@x); __END__ $VAR1 = [ 1, 1, 1, 1 ];

    BTW, you had @x[1..3] I changed it @x[0..3]. I felt that is probably what you want as the array index starts with zero. If you are sure you don't need zero then you can modify my code.

    -SK

Re: Initialization of arrays
by Moron (Curate) on Sep 22, 2005 at 14:00 UTC
    OK for what? Tell us what you want and maybe we can tell you how to do it. If, for example, you want what you expected, it can be done explicitly with:
    @x = ('',1,1,1,'','','','','','',1);

    -M

    Free your mind