Hi all,

> 
> You are right -- but this produces 4 first, as I had always thought it
> would, and then 6, as I don't quite understand.  I would never use
> that kind of expression, and I sorta maybe understand why it says 6,
> but only in hindsight.
> 
>     #!/usr/bin/perl
> 
>     my @ary = (1,2,,4,,6);
>     print "Step 1: ", scalar(@ary), "\n";
>     print "Step 2: ", scalar(1,2,,4,,6), "\n";

In the first example, scalar is operating on the array to give you its size. So 
you do indeed get 4, because only 4 elements are allocated. That is *indeed* an 
unusual and somewhat apparently counterintutive feature since very often in 
Perl, otherwise "undefined values" have storage autovifified when assigned 
under the hood and if interrogated with the defined operator will give you 
false. i.e. "the box is there but empty".

If you want to tell if the element is there at all - you can use exists.

E.g. 

print "Hi there element 4\n" if exists $ary[4];
print "Hi there element 5\n" if exists $ary[5];

which - in the case of @ary above would not print anything since only elements 
0..3 exist.

If you wanted 6 elements, as was noted earlier, you would have to preserve the 
indexing of the "missing" elements by using undef (see below).

In the 2nd example, as we've noted, - you are simply getting the last value in 
a list - 6  in this case.

So, the question is - why does Perl not keep the otherwise "undefined" elements 
in the list when they are being represented by ,, ?

And the answer is unusual in that it's still seeing 

my @ary = (1,2,,4,,6);

as a sequence on the right hand side - in which there are only 4 scalar items.

So, to make it have 6, you'd say:

my @ary = (1,2,undef,4,undef,6);

That will autovivify all 6 elements, each of which will exist now according to 
exists, but only 4 of which will have defined values according to defined.

Here's an updated version of your example:

------

#!/usr/bin/perl

print "Original\n";

my @ary = (1,2,,4,,6);

print "Step 1: ", scalar(@ary), "\n";
print "Step 2: ", scalar(1,2,,4,,6), "\n";

print "Hi there element 4\n" if exists $ary[4]; # Does not print
print "Hi there element 5\n" if exists $ary[5]; # Does not print

print "New\n";

my @ary2 = (1,2,undef,4,undef,6);

print "Step 1: ", scalar(@ary2), "\n";
print "Step 2: ", scalar(1,2,undef,4,undef,6), "\n";

print "Hi there element 4\n" if exists $ary2[4];  #Now prints
print "Hi there element 5\n" if exists $ary2[5]   #Now prints


------

This is somewhat counterintuitive in that, if you had an array where you 
specified the size of a slice on the left, Perl would automatically allocate 
that number of elements and automatically assign undef to the ones not 
otherwise filled. But…. not in the way you expect.

E.g.

@ary3[0..5] = (1,2,,4,,6);

Does *not* preserve the gaps - for the exact same reason as above. But, you do 
get elements 4 and 5 now - but it's *those* that are undef - and the actual 
list (1,2,4,6) gets assigned to elements 0..3

E.g.


print "New2\n";

my @ary3;

@ary3[0..5] = (1,2,,4,,6);

print "Size: ", scalar(@ary3), "\n";

print "Hi there element 4\n" if exists $ary3[4];  #Prints
print "Hi there element 5\n" if exists $ary3[5];  #Prints

print "Hidef 4\n" if defined $ary3[4];  #Does not print
print "Hidef 5\n" if defined $ary3[5];  #Does not print


$"=":";

print "Elements\n";

print "-->@ary3<--\n";   # Notice the empty (undefined) two elements at the 
*end*… ;-)

Kind regards

Derek.

Reply via email to