[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ next ]


Perl notes
Chapter 2 - Lists and Arrays


A list is defined as an ordered collection of scalars, and an array is a variable that contains a list. Each element is an independent scalar value and a list can hold a mixture of different scalars (numbers and strings).


2.1 Defining and Accessing an Array

When using the strict pragma it is necessary to declare an array before it is first used. The character that defines a variable as an array variable is @. Thus, to define an array called replicants we execute[3]:

     my @replicants;

The array elements are numbered using sequential integers, starting at zero, and each array element behaves as an scalar variable

     my @replicants;
     #
     $replicants[0] = "roy";
     $replicants[1] = "leon";
     $replicants[2] = "pris";
     $replicants[3] = "zhora";
     #
     print "$replicants[1]\n";
     #
     my $index = 3; 
     print $replicants[$index-1],"\n"; # floating-point indexes truncate to the next lower integer.

The storage of an array element beyond the end of the array extends the array size, with intervening elements created as undef values.

     #
     $replicants[10] = "rachel"; # six undef elements
     #

The last index of the array replicants is $#replicants, which is the number of elements minus one

     #
     my $end = $#replicants;
     my $number_of_replicants = $end + 1;
     print "$replicants[$end]\n";
     #

To extract elements from the end of the list a negative index can be used.

     #
     print "$replicants[-1]\n";
     print "$replicants[-8]\n";
     #

2.1.1 List Literals

A list literal is how a list is represented in the code, as a list of comma separated values between parentheses. In this case the range operator (..) can be used.

     @replicants = ("zhora", "pris", "leon", "rachel", "roy");
     my @numbers = (12, 32, 13, 44, 14, 66);
     my @elist = (); # Empty list - zero elements
     my @list_1 = (1..100);
     my @list_2 = (0..10, 50..100);
     my @list_3 = ($replicants[1], $replicants[0], 45 + $list_2[3]);

The qw (quoted word) shortcut simplifies the list definition:

     my @numbers = qw(12 32 13 44 14 66);

The elements are treated as single-quoted strings and it allows to choose any punctuation character as a delimiter

     @numbers = qw!12 32 13 44 14 66!;
     @numbers = qw/12 32 13 44 14 66/;
     @numbers = qw<12 32 13 44 14 66>;

2.2 List Assignment

You can assign list values to variables and easily swap variables' values

     my ($var_1, $var_2, $var_3) = ("one", "two", "three");
     @replicants = ("zhora", "pris");
     @replicants = ("pris", "zhora",);

If there are extra values in the right side they are ignored, and if there are extra values in the left side they are given the undef value. You can mix arrays and scalars

     my @characters = (@replicants,"deckard","gaff");

And you can easily copy an array into another array

     my @copy_arr = @characters;

2.3 Interpolating Arrays

An array into a double-quoted string is interpolated, their values expanded, separating the elements by spaces.

     print "The replicants are @replicants\n";

Thus, it is important to be careful when including the character @ in a double-quoted string. For example, to define a variable containing an email address once should do it in one of these two alternative ways

     my $email;
     $email = "sebastian\@tyrell.com";
     $email = 'sebastian@tyrell.com';

A single element array interpolates into its value

     print "The 3rd element of the array \@replicants is $replicants[2].\n";

2.4 Array Operators


2.4.1 Operators pop and push

An array can be considered as an stack of information, where you add and remove from the end of the array using the operators push and pop.

     print pop @numbers, "\n";
     print "$#numbers\n";
     push @numbers, 20;
     push @numbers, 1..60;

2.4.2 Operators shift and unshift

This is equivalen to the previous case but the programs take and add elements to the beginning of the list.

     print shift @numbers, "\n";
     shift @numbers;
     print "$numbers[1]\n";
     unshift @numbers, 10;
     print "$numbers[1]\n";
     unshift @numbers, 1..60;
     print "$numbers[1]\n";

2.4.3 The splice Operator

This operator takes a maximum of four arguments and allows to work with sections of an array, deleting or adding elements at any place.

The last two arguments are optional. The first argument is the array and the second is the starting position. If only this two arguments are used Perl removes all the elements from the starting position to the end of the array and returns them to you.

The third argument is a length making possible to remove some elements from the middle of the array. The fourth argument is a replacement list that is added to the array in the position stated by the second argument. Thus you can remove and add elements in a single statement. If no elements should be deleted, then argument three is made equal to zero.

As with scalars, array values between double quotes are interpolated.

     print "\@characters = @characters\n";
     my @array = splice @characters, 2; # remove everything after the third array element
     print "\@array = @array\n";
     print "\@characters = @characters\n";
     my @removed_1 = splice @numbers, 3, 6;
     my @new_array = splice @numbers, 3, 0, 1..5;

2.4.4 The reverse Operator

This operator takes a list of values as an argument and returns the list in the opposite order.

     my @num_range = 1..10;
     print "@num_range\n";
     my @reversed_num_range = reverse @num_range;
     print "Original array = @num_range\n";
     print "Reversed array = @reversed_num_range\n";

2.4.5 The sort Operator

This operator takes a list of values as an argument and returns the list sorted according to the internal character values (code point order).

     my @sorted_characters = sort @characters;
     print "Original array = @characters\n";
     print "Sorted array = @sorted_characters\n";
     my @sorted_num_range = sort @num_range;
     print "Original array = @num_range\n";
     print "Sorted array = @sorted_num_range\n";

2.4.6 The each Operator

This operator[4] takes an array as an argument and each time it is called returns a pair of values (index, array_value):

     while (my ($index_value, $array_element) = each @characters) {
        print "Index: $index_value\tElement:  $array_element\n";
     }

2.4.7 Array clearing

The correct way to clear an array is to assign the array to an empty list

     @replicants = ("leon", "pris", "zhora");
     .
     .
     .
     @replicants = (); # The array is emptied

Note that this is different from

     @replicants = ("leon", "pris", "zhora");
     .
     .
     .
     @replicants = undef; # The array is the one-element list (undef)

2.5 The foreach control structure

This is a useful control structure to process every element of a list, one at a time, and executing a block of instructions each iteration. For example

     print "Contents of \@characters:\n";
     foreach my $chtr (@characters) {
        print "$chtr\n";
     }

Be careful because if you modify the control variable ($chtr in the example) you modify the actual list element. For example, if you want to precede every list element by a tab adn add a newline character after the list element

     print "Contents of \@characters: @characters\n";
     foreach my $chtr (@characters) {
        $chtr = "\t$chtr";
        $chtr .= "\n";
     }
     print "Contents of \@characters: @characters\n";

2.5.1 Perl's default scalar variable $_.

If the control variable is omitted in the definition of the foreach control structure the default variable is used: $_. For example

     foreach (1..20) {
       print;
       print "$_ ", 2*$_, " ", 3*$_, " ", 4*$_,"\n";
     }

This is by large the most commonly used default variable in Perl. In many cases, when a variable is needed and no name is provided, Perl will use $_ as a replacement.


2.6 Scalar and List context

In Perl a given expression can have a different meaning according to the context, thus according where it appears and how it is used. This is common in natural languages. Considering scalars and lists, when Perl parses a particular expression, it expects either a scalar or a list value. For example

     99 + something # Something should be a scalar (scalar context)
     sort something # Something should be a list (list context)

If something is the same exact sequence of characters, it may give completely different values depending on the evaluation context. For example, an array variable would give the list of elements in a list context while in scalar context it would give the number of elements of the list.

     my @characters = ("leon","deckard","gaff");
     @sorted = sort @characters; # list context :: deckard gaff leon
     my $i = 22 + @characters; # scalar context :: i = 22 + 3 = 25

Each expression can have different output according to the evaluation context.


2.6.1 List-producing expressions in scalar context.

In principle you should check the documentation to see what is the output in scalar context of expressions that are usually used to produce a list. Some expression (e.g. sort) have no scalar-context value. Others have a different value according to the context, like reverse

     my @characters = ("leon","deckard","gaff");
     @reversed = reverse @characters; # list context :: gaff deckard leon
     $reversed = reverse @characters; # scalar context :: noeldrakcedffag

Some scalar context examples

     $variable = something;
     $tyrell[3] = something;
     1234 +  something;
     if (something) { ... 
     while (something) { ... 
     $tyrell[something] = something;

Some list context examples

     @variable = something;
     ($tyrell,$sebastian) = something;
     ($tyrell) =   something;
     push @tyrell, something;
     foreach (something) { ... 
     sort something;
     print something;

2.6.2 Scalar-producing expressions in list context.

The use of a scalar-producing expression in list context always results in the promotion of the scalar to a one-element list.

     @output = 6*12; # One-element list (72)

2.6.3 STDIN in list context.

The line-input operator STDIN in list context returns a list with all the remaining lines up to an end-of-file, each line is a separate list element. For example, reading several lines and removing the end-of-lines:

     @input = <STDIN>;
     chomp(@input);

Input from a file will be read until the end of the file, while keyboard input should be stopped with the end-of-file key combination, normally CTRL-D in UNIX systems. You can chomp all lines simultaneously

     chomp (@input = <STDIN>);

[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ next ]


Perl notes

$Id: perl_notes.sgml,v 1.3 2011/12/12 15:41:58 curro Exp curro $

Curro Pérez Bernal francisco.perez@dfaie.uhu.es