17 Part 15: More About Lists

LinuxChix Perl Course Part 15: More About Lists

1) Introduction
2) Flat Lists
3) The Length of an Array
4) The "foreach" Loop
5) Exercises
6) Answer to Previous Exercise
7) Past Information
8) Credits
9) Licensing

-----------------------------------

1) Introduction

Last week we saw the very basics of array variables in Perl. This week
we're still looking at the basics, but slightly higher-level basics.

By the way, last week I used the term "array", mainly because I thought
it would be more familiar. The general term in Perl is "list". An array
is actually a type of list: a named list. Of course, we can informally
use the terms interchangeably.

-----------------------------------

2) Flat Lists

As we saw last week, lists in Perl are "flat": that is, they must
contain only scalars. This obviously makes certain complex data
structures more difficult to represent, but it has the advantage of
making lists easy to join and split. For example, the following will
join three lists into one big list:

my @everyone = (@men, @women, @children);

Remember that arrays are always assigned by value, so subsequent changes
to, say, "@women" will have no effect on "@everyone".

Likewise, the following will insert "$new_guy" at position 5 of the
array (pushing all the other elements back one, of course):

@everyone = (@everyone[0..4], $new_guy, @everyone[5..-1]);

And we can even use a list of variables as an lvalue (something to
assign to). We've already seen that in statements like this:

my($hour,$minute,$second) = ($time =~ m/(\d+):(\d+):(\d+)/);

The "m//" operator returns a list, "$hour" is set to the first value of
that list, "$minute" is set to the second value of the list, etc.

Note that if the number of elements on the left and right sides of the
assignment don't match, no error message is produced:

($a, $b) = ('one', 'two', 'three'); # Same as: $a='one'; $b='two';
($a, $b, $c) = ('one', 'two'); # Ditto, but sets $c to undef!

If one of the lvalues is an array, the array sucks up all remaining values:

($first,$second,@rest) = @everyone;

This means that it's a mistake (not an error, but surely a mistake) to
follow an array with another variable in an assignment:

(@rest,$last) = @everyone; # NO! Same as: @rest=@everyone; $last=undef
(@a, @b) = qw/a list of words/; # Likewise not good.
(@a, @b) = (@c, @d); # NOT the same as @a=@c; @b=@d;

-----------------------------------

3) The Length of an Array

To find the length of an array, simply assign the array to a scalar
variable:

my @arr = ('foo', 'bar', 'baz');
my $length = @arr;
print "Length is: $length\n";

We'll see more about this next week.

By the way, don't try this with a literal list:

my $length_but_doesnt_work = ('foo', 'bar'); # Sets to "bar".

I'm sorry; I should have mentioned this last week.

-----------------------------------

4) The "foreach" Loop

To loop through the values of an array, you could use a "for" loop:

my @foo = qw/one two three four/;
for (my $i=0; $i<@foo; $i++) {
print "$foo[$i]\n";
}

However, it's usually easier to use a "foreach" loop:

my @foo = qw/one two three four/;
foreach my $value (@foo) {
print "$value\n";
}

If no scalar variable is provided in the "foreach" statement, "$_" is used:

my @foo = qw/one two three four/;
foreach (@foo) {
print "$_\n";
}

In this case (and ONLY in this case), changes to "$_" affect the array:

my @foo = qw/one two three four/;
foreach (@foo) {
s/[aeiou]/X/g; # Replace vowels with "X".
}
print "@foo\n"; # The array now has no vowels.

We'll see a similar way to change the values of an array when we look at
the "map" operator.

-----------------------------------

5) Exercises

a) Fix last week's "tail" program to take into account the possiblity
that the user inputs a small number of lines. (See below.)

b) The Perl function "reverse" reverses the order of an array. Write
your own implementation of "reverse", i.e.:

my @array = qw/A B C D E F G/;

# Your code here.

print "Result is: @result\n";

Try to use "foreach" instead of "for".

-----------------------------------

6) Answer to Previous Exercise

Here is an implementation of "tail" in Perl:

#!/usr/bin/perl -w
use strict;

my $lines_to_output = 10;

my @lines = <>;
print @lines[ -$lines_to_output .. -1 ];

Again, this program is faulty because it assumes that there are at least
ten lines of input. If there are less than ten lines, the Perl
interpreter will complain because we're printing the undefined value
("undef").

It really was stupid of me to suggest that you write a buggy program.
Please excuse me.

-----------------------------------

7) Past Information

Part 1: Getting Started
http://linuxchix.org/pipermail/courses/2003-March/001147.html

Part 2: Scalar Data
http://linuxchix.org/pipermail/courses/2003-March/001153.html

Part 3: User Input
http://linuxchix.org/pipermail/courses/2003-April/001170.html

Part 4: Control Structures
http://linuxchix.org/pipermail/courses/2003-April/001184.html

Part 4.5, a review with a little new information at the end:
http://linuxchix.org/pipermail/courses/2003-July/001297.html

Part 5: The "tr///" Operator
http://linuxchix.org/pipermail/courses/2003-July/001302.html

Part 6: The "m//" Operator
http://linuxchix.org/pipermail/courses/2003-August/001305.html

Part 7: More About "m//"
http://linuxchix.org/pipermail/courses/2003-August/001322.html

Part 8: The "s///" Operator
http://linuxchix.org/pipermail/courses/2003-August/001330.html

Part 9: Simple File Access
http://linuxchix.org/pipermail/courses/2003-September/001340.html

Part 10: Executing Commands with "open"
http://linuxchix.org/pipermail/courses/2003-September/001344.html

Part 11: Perl Variables
http://linuxchix.org/pipermail/courses/2003-October/001345.html

Part 12: Side Effects with Perl Variables
http://linuxchix.org/pipermail/courses/2003-October/001347.html

Part 13: Perl Style
http://linuxchix.org/pipermail/courses/2003-October/001349.html

Part 14: Arrays
http://linuxchix.org/pipermail/courses/2003-October/001350.html

-----------------------------------

8) Credits

Works cited:
a) man perldata
b) man perlfunc

Thanks to Jacinta Richardson for fact checking.

-----------------------------------

9) Licensing

This course (i.e., all parts of it) is copyright 2003 by Alice Wood and
Dan Richter, and is released under the same license as Perl itself
(Artistic License or GPL, your choice). This is the license of choice to
make it easy for other people to integrate your Perl code/documentation
into their own projects. It is not generally used in projects unrelated
to Perl.