[Courses] [Perl] Part 16: Array Functions

Dan Richter daniel.richter at wimba.com
Thu Nov 13 14:34:28 EST 2003

LinuxChix Perl Course Part 16: Array Functions

1) Introduction
2) Re-Visiting Old Perl Functions
3) Six Simple Functions
4) Consider the Context
5) Exercise
6) Answers to Previous Exercises
7) Past Information
8) Credits
9) Licensing


1) Introduction

Perl includes many functions that make handling arrays a breeze.

Some of these functions are quite versatile, i.e., you can change the 
way they work if you need a slightly different behaviour. We could never 
get through all the different customisations that can be done, but you 
can find out more about any one of these functions by typing
"perldoc -f <function name>" at the command-line.


2) Re-Visiting Old Perl Functions

Some Perl functions that we've already seen will accept either scalars 
or lists. For example, we've seen the "chomp" function used with 
scalars, but it can also be used with a list (in which case it chomps 
every element of the list):

   chomp($a, $list, $of, $scalars);

But not all Perl functions can do this. For example, the "uc" function 
capitalises all the letters in a string, but it won't accept a list. 
Always RTFM to make sure.


3) Six Simple Functions

We're going to start with

a) split - splits a string into an array
b) join - combines an array to form a string
c) reverse - reverses the order of an array (first element becomes last)
d) sort - puts the array in alphabetical order (NOT numerical order)
e) push - adds one or more values to the end of an array
f) pop - removes and returns the last element of an array


   my @arr = split( /[#!]+/, 'foo###bar!!!baz' );
       # Now @arr = ('foo', 'bar', 'baz')
   print join('**', @arr);      # Output is: "foo**bar**baz"
   @arr = reverse(@arr);        # Now @arr = ('baz', 'bar', 'foo')
   @arr = sort(@arr);           # Now @arr = ('bar', 'baz', 'foo')
   my $x = pop(@arr);           # Now $x='baz' and @arr=('foo', 'bar')
   push(@arr, 'Bob', 'Jane');   # Now: ('foo', 'bar', 'Bob', 'Jane')

Note that only the functions "push" and "pop" change the array variable 
passed in. This means that the other functions can take any list, not 
just an array:

   my @arr = ('foo', 'bar', 'baz');
   print join('**', @arr);      # Output is: "foo**bar**baz"
   print join('**', 'foo', 'bar', 'baz');  # Same as previous line
   print join('**', 'A', @arr, 'B');  # Output: "A**foo**bar**baz**B"


4) Consider the Context

Many Perl functions and operators behave differently depending on the 
"context". Perl has three possible contexts: scalar context, list 
context and void context:

   my @arr = ('foo', 'bar', 'baz');
   my @a = reverse(@arr);       # Array context
   my $s = reverse(@arr);       # Scalar context
   reverse(@arr);               # Void context

   print "@a\n";       # Output is: baz bar foo
   print "$s\n";       # Output is: zabraboof (foobarbaz backwards)

Note that the context is determined by how the return value is used, NOT 
the parameters passed to the function/operator. This is quite Perl-like; 
most languages have functions that always return the same value, no 
matter how it's used.

The use of an array (variable) in scalar context returns the length of 
the array:

   my @array = ('foo', 'bar', 'baz');
   my $scalar = @array;
   print "$scalar\n";      # Output is 3.

But don't try this with a literal list:

   my $scalar = ('foo', 'bar', 'baz');       # Warnings generated here.
   print "$scalar\n";      # Output is baz.

In the above cases the context was obvious because we assigned to an 
array or scalar variable. But the context can also be indicated by an 
operator. For example, arithmetic operators are all scalar, as is string 

   print "The length of the array is: " . @array . "\n";

We can also force scalar context by using the "scalar" operator:

   ($length_a, $length_b) = (scalar @a, scalar @b);

"man perlfunc" tells us: "There is no equivalent operator to force an 
expression to be interpolated in list context because in practice, this 
is never needed."


5) Exercise

Write a Perl program that reads /etc/passwd and outputs just a list of 
usernames and UIDs, ordered alphabetically by username. Remember: There 
Is More Than One Way To Do It.


6) Answers to Previous Exercises

a) Here is a tail program that works on even a small number of lines.

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

   my @lines = <>;

   my $lines_to_output = @lines;     # Get number of lines.
   $lines_to_output = 10 if $lines_to_output > 10;  # Limit number of lines.

   print @lines[ -$lines_to_output .. -1 ];

b) Here is a reversal algorithm.

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

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

   my @result;
   foreach my $element (@array) {
     @result = ($element, @result);

   print "Result is: @result\n";

As you might guess, it would be a little more efficient to use "push" 
and "pop", but we hadn't seen these functions last week. (Calling the 
"reverse" function would be more efficient still! :-)


7) Past Information

Part 1: Getting Started

Part 2: Scalar Data

Part 3: User Input

Part 4: Control Structures

Part 4.5, a review with a little new information at the end:

Part 5: The "tr///" Operator

Part 6: The "m//" Operator

Part 7: More About "m//"

Part 8: The "s///" Operator

Part 9: Simple File Access

Part 10: Executing Commands with "open"

Part 11: Perl Variables

Part 12: Side Effects with Perl Variables

Part 13: Perl Style

Part 14: Arrays

Part 15: More About Lists


8) Credits

Works cited: 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