[Courses] [Perl] Part 15: More About Lists

Dan Richter daniel.richter at wimba.com
Thu Nov 6 13:58:42 EST 2003


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, at 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.




More information about the Courses mailing list