home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Perl CookbookPerl CookbookSearch this book

4.3. Changing Array Size

4.3.3. Discussion

$#ARRAY is the number of the last valid index in @ARRAY. If we assign it a number smaller than its current value, we truncate the array. Truncated elements are lost forever. If we assign $#ARRAY a number larger than its current value, the array grows. New elements have the undefined value.

$#ARRAY is not @ARRAY, though. Although $#ARRAY is the last valid index in the array, @ARRAY (in scalar context, as when treated as a number) is the number of elements. $#ARRAY is one less than @ARRAY because array indices start at 0.

Here's some code that uses both. We have to say scalar @array in the print because Perl gives list context to (most) functions' arguments, but we want @array in scalar context.

sub what_about_that_array {
    print "The array now has ", scalar(@people), " elements.\n";
    print "The index of the last element is $#people.\n";
    print "Element #3 is `$people[3]'.\n";
}

@people = qw(Crosby Stills Nash Young);
what_about_that_array( );

prints:

The array now has 4 elements.
The index of the last element is 3.
Element #3 is `Young'.

whereas:

$#people--;
what_about_that_array( );

prints:

The array now has 3 elements.
The index of the last element is 2.
Element #3 is ''.

Element #3 disappeared when we shortened the array. If we'd turned on warnings (either with the -w command-line option to Perl or with use warnings inside the program), Perl would also have warned "use of uninitialized value" because $people[3] is undefined.

$#people = 10_000;
what_about_that_array( );

prints:

The array now has 10001 elements.
The index of the last element is 10000.
Element #3 is ''.

The "Young" element is now gone forever. Instead of assigning to $#people, we could have said:

$people[10_000] = undef;

although this isn't exactly the same. If you have a three-element array, as in:

@colors = qw(red blue green);

and you undef its last element:

undef $colors[2];        # green is gone

you still have a three-element array; its last element is just undefined. If you pop the array, either via the function or manually by changing $#colors:

$last_color = $colors[ $#colors-- ];

then the array grows shorter by one element.

Perl arrays are not sparse. In other words, if you have a 10,000th element, you must have the 9,999 other elements, too. They may be undefined, but they still take up memory. For this reason, $array[time( )], or any other construct that uses a very large integer as an array index, is a really bad idea. Use a hash instead.

4.3.4. See Also

The discussion of the $#ARRAY notation in perldata(1), also explained in the "List Values and Arrays" section of Chapter 2 of Programming Perl



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.