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

Hi monks,

I am having problems finding the real length of an array with null values at the right of the array:

my @array = (1,2,3,4,5,6,7,8,9); my @array_2 = (1,2,3,4,5,6,7,8,9,,,,,,); print "Scalar of array 1 =",scalar @array,"\n"; print "Scalar of array 2 =",scalar @array_2,"\n";
returns:
bash-2.03$ perl test.pl Scalar of array 1 =9 Scalar of array 2 =9 bash-2.03$
Is there any way to get the real length of the array rather than the length up till the last non-empty field? Maybe something like the modifier to split:
#split but do not toss out empty fields split ("\t",string,999999)

I appreciate the help,
Hackmare

Replies are listed 'Best First'.
•Re: find real length of an array
by merlyn (Sage) on Mar 16, 2003 at 15:59 UTC
    The commas on the right of your intiialization do not create null elements. They are tossed as a syntax convenience. So both of your example arrays do indeed have only 9 elements in them. You can see that by pushing something onto either one: the length will go to 10.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      Thanks for the quick reply.

      In my real source code in the offending application, the offending array is constructed from a split of a tab-delimited line. I am using split("\t",$line,99999) to generate the line.

      Hmmm... When I run the test below on the command line, it seems to behave correctly I have a feeling that I need to take a close look at the offending code. All the splits which I am using to generate the array are providing the field number option, which inserts undefs into the placeholders. Well, at least the answers I got here helped me cross out some of the possible sources of error. Thanks for the help.

      bash-2.03$ cat test.pl #!/usr/bin/perl my $line = "hello\tworld\tI\tam\ta\tline\twithout\ttabs"; my $line_2 = "hello\tworld\tI\tam\ta\tline\twith\ttabs\t\t\t\t"; my @array = split("\t",$line,9999); my @array_2 = split("\t",$line_2,9999); my @array_3 = split("\t",$line_2); print "Scalar of array 1 =",scalar @array,"\n"; print "Scalar of array 2 =",scalar @array_2,"\n"; print "Scalar of array 3 =",scalar @array_3,"\n"; bash-2.03$ perl test.pl Scalar of array 1 =8 Scalar of array 2 =12 Scalar of array 3 =8 bash-2.03$

      Ronan
      www.roasp.com

        This has nothing to do with array behaviour in general, but solely with the way split behaves. Note that if you really want to conserve all trailing fields, instead of passing 99999, you should give it -1. This is documented in perlfunc:
        If LIMIT is specified and positive, splits into no more than that many fields (though it may split into fewer). If LIMIT is unspecified or zero, trailing null fields are stripped (which potential users of pop would do well to remember). If LIMIT is negative, it is treated as if an arbitrarily large LIMIT had been specified.

        Makeshifts last the longest.

Re: find real length of an array
by jand (Friar) on Mar 16, 2003 at 16:02 UTC
    You are getting the real length of the array. Appending additional commas doesn't extend the length of the array. You would have to write this as:
    my @array_2 = (1,2,3,4,5,6,7,8,9,undef,undef,undef,undef,undef,undef);
    or
    my @array_2 = (1,2,3,4,5,6,7,8,9); $array_2[14] = undef;
    The reason that trailing commas are not a syntax error is so that you can write code like this:
    my %hash = ( a => 1, b => 2, );
    If the comma added another "undef" to the list then you would get a warning:
    Odd number of elements in hash assignment. Use of uninitialized value in list assignment.
Re: find real length of an array
by pg (Canon) on Mar 16, 2003 at 18:24 UTC
    hackmare, the problem is with your regexp. Check out the following demo, you actually got whole bunch of "" in your array.
    use strict; my $str = "abc\t\t\t\t\thij\t\t\t\t\t"; my @a = split("\t", $str, 99999); for (0..$#a) { if (defined($a[$_])) { print "element $_ is $a[$_]\n"; } else { print "element $_ is undef\n"; } } print $#a; #print out 10
    Change your regexp to something like:
    split(/\t+/, $str, 99999);
    should help you. After the change, it prints out 2. (There is still one empty string at the end, but now much easy to handle)

      Sorry, the code above is just a quick example. The real code does exactly what you have above (using a real regex).
      hackmare.

Re: find real length of an array
by artist (Parson) on Mar 16, 2003 at 16:35 UTC
    Why you want to do that? Having just ',' will not work and pushing 'undef' is a not good idea from my perspective. There must be some alternative ways to complete what you want to do. State the underlying problem and we will have better solution.

    artist

      This is the result of splitting on a string with empty tab-delimited fields. (see reply to merlyn above w/ example.)

      hackmare.

Re: find real length of an array
by hackmare (Pilgrim) on Mar 16, 2003 at 15:48 UTC

    Oops, I thought I was logged in when I posted.
    hackmare.