A list is an ordered collection of scalars. An array is a variable that contains a list. In Perl, the two terms are often used as if they’re interchangeable. But, to be accurate, the list is the data, and the array is the variable. You can have a list value that isn’t in an array, but every array variable holds a list (although that list may be empty).
Accessing Elements of an Array
The array elements are numbered using sequential integers, beginning at zero and increasing by one for each element, like this:
$fred[0] = "yabba";
$fred[1] = "dabba";
$fred[2] = "doo";
The array name itself (in this case, "fred") is from a completely separate namespace than scalars use; you could have a scalar variable named $fred
in the same program, and Perl will treat them as different things and wouldn’t be confused.(But don't do that!)
The subscript may be any expression that gives a numeric value. If it’s not an integer already, it’ll automatically be truncated to the next lower integer:
$number = 2.71828;
print $fred[$number − 1]; # Same as printing $fred[1]
Special Array Indices
If you store into an array element that is beyond the end of the array, the array is automatically extended as needed—there’s no limit on its length, as long as there’s available memory for Perl to use. If Perl needs to create the intervening elements, it creates them as undef
values:
$rocks[0] = 'bedrock'; # One element...
$rocks[1] = 'slate'; # another...
$rocks[2] = 'lava'; # and another...
$rocks[3] = 'crushed rock'; # and another...
$rocks[99] = 'schist'; # now there are 95 undef elements
Sometimes, you need to find out the last element index in an array. For the array of rocks that we’ve just been using, the last element index is $#rocks
.* That’s not the same as the number of elements, though, because there’s an element number zero:
$end = $#rocks; # 99, which is the last element's index
$number_of_rocks = $end + 1; # okay, but you'll see a better way later
$rocks[$#rocks] = 'hard rock'; # the last rock
Using the $#name
value as an index, like that last example, happens often enough that Larry has provided a shortcut: negative array indices count from the end of the array. But don’t get the idea that these indices “wrap around.” If you’ve got three elements in the array, the valid negative indices are −1 (the last element), −2 (the middle element), and −3 (the first element). In the real world, nobody seems to use any of these except −1, though.
$rocks[ −1 ] = 'hard rock'; # easier way to do that last example
$dead_rock = $rocks[−100]; # gets 'bedrock'
$rocks[ −200 ] = 'crystal'; # fatal error!
List literals
An array (the way you represent a list value within your program) is a list of comma- separated values enclosed in parentheses. These values form the elements of the list. For example:
(1, 2, 3) # list of three values 1, 2, 3
(1, 2, 3,) # the same three values(the trailing comma is ignored)
("fred", 4.5) # two values, "fred" and 4.5
() # empty list - zero elements
(1..100) # list of 100 inegers
That last one uses the .. range operator, which is seen here for the first time. That operator creates a list of values by counting from the left scalar up to the right scalar by ones. For example:
(1..5) # same as (1, 2, 3, 4, 5)
(1.7..5.7) # same thing - both values are truncated
(5..1) # empty list - .. only counts "uphill"
(0, 2..6, 10, 12) # same as (0, 2, 3, 4, 5, 6, 10, 12)
($m..$n) # range determined by current values of $m and $n
(0..$#rocks) # the indices of the rocks array from the previous section
Of course, a list may have any scalar values, like this typical list of strings:
("fred", "barney", "betty", "wilma", "dino")
The qw shortcut
It turns out that lists of simple words (like the previous example) are frequently needed in Perl programs. The qw shortcut makes it easy to generate them without typing a lot of extra quote marks:
qw( fred barney betty wilma dino ) # same as above, but less typing
qw
stands for “quoted words” or “quoted by whitespace,” depending upon whom you ask. Either way, Perl treats it like a single-quoted string (so, you can’t use \n
or $fred
inside a qw
list as you would in a double-quoted string). The whitespace (characters like spaces, tabs, and newlines) will be discarded, and whatever is left becomes the list of items. Since whitespace is discarded, here’s another (but unusual) way to write that same list:
qw(fred
barney betty
wilma dino) # same as above, but pretty strange whitespace
Since qw
is a form of quoting, though, you can’t put comments inside a qw
list. The previous two examples have used parentheses as the delimiter, but Perl actually lets you choose any punctuation character as the delimiter. Here are some of the common ones:
qw! fred barney betty wilma dino !
qw/ fred barney betty wilma dino /
qw# fred barney betty wilma dino #
qw( fred barney betty wilma dino )
qw{ fred barney betty wilma dino }
qw[ fred barney betty wilma dino ]
qw< fred barney betty wilma dino >
As those last four show, sometimes the two delimiters can be different. If the opening delimiter is one of those “left” characters, the corresponding “right” character is the proper closing delimiter. Other delimiters use the same character for start and finish.
If you need to include the closing delimiter within the string as one of the characters, you probably picked the wrong delimiter. But even if you can’t or don’t want to change the delimiter, you can still include the character using the** backslash**:
qw! yahoo\! google ask msn ! # include yahoo! as an element
.
As in single-quoted strings, two consecutive backslashes contribute one single backslash to the item.
Examples:
qw{
/usr/dict/words
/home/rootbeer/.ispell_english
}
List Assignment
In much the same way as scalar values may be assigned to variables, list values may also be assigned to variables:
($fred, $barney, $dino) = ("flintstone", "rubble", undef);
All three variables in the list on the left get new values, just as if you did three separate assignments. Since the list is built up before the assignment starts, this makes it easy to swap two variables’ values in Perl:
($fred, $barney) = ($barney, $fred); # swap those values
($betty[0], $betty[1]) = ($betty[1], $betty[0]);
In a list assignment, extra values are silently ignored—Perl figures that if you wanted those values stored somewhere, you would have told it where to store them. Alternatively, if you have too many variables, the extras get the value undef
:
($fred, $barney) = qw< flintstone rubble slate granite >; # two ignored items
($wilma, $dino) = qw[flintstone]; # $dino gets undef
But when you wish to refer to an entire array, Perl has a simpler notation. Just use the at sign (@) before the name of the array (and no index brackets after it) to refer to the entire array at once. You can read this as “all of the,” so @rocks
is “all of the rocks.” This works on either side of the assignment operator:
@rocks = qw/ bedrock slate lava /;
@tiny = ( ); # the empty list
@giant = 1..1e5; # a list with 100,000 elements
@stuff = (@giant, undef, @giant); # a list with 200,001 elements
$dino = "granite";
@quarry = (@rocks, "crushed rock", @tiny, $dino);
It’s worth noting that when an array is copied to another array, it’s still a list assignment. The lists are simply stored in arrays. For example:
@copy = @quarry; # copy a list from one array to another
The pop and push Operators
The pop
operator takes the last element off of an array and returns it:
@array = 5..9;
$fred = pop(@array); # $fred gets 9, @array now has (5, 6, 7, 8)
$barney = pop @array; # $barney gets 8, @array now has (5, 6, 7)
pop @array; # @array now has (5, 6). (The 7 is discarded.)
If the array is empty, pop
will leave it alone (since there is no element to remove), and it will return undef
.
push(@array, 0); # @array now has (5, 6, 0)
push @array, 8; # @array now has (5, 6, 0, 8)
push @array, 1..10; # @array now has those ten new elements
@others = qw/ 9 0 2 1 0 /;
push @array, @others; # @array now has those five new elements (19 total)
The shift and unshift operators
The push
and pop
operators do things to the end of an array (or the right side of an array, or the portion with the highest subscripts, depending upon how you like to think of it). Similarly, the unshift
and shift
operators perform the corresponding actions on the “start” of the array (or the “left” side of an array, or the portion with the lowest subscripts). Here are a few examples:
@array = qw# dino fred barney #;
$m = shift(@array); # $m gets "dino", @array now has ("fred", "barney")
$n = shift @array; # $n gets "fred", @array now has ("barney")
shift @array; # @array is now empty
$o = shift @array; # $o gets undef, @array is still empty
unshift(@array, 5); # @array now has the one-element list (5)
unshift @array, 4; # @array ow has (4, 5)
@others = 1..3;
unshift @array, @others; # @array now has (1, 2, 3, 4, 5)
Interpolating Arrays into Strings
Like scalars, array values may be interpolated into a double-quoted string. Elements of an array are automatically separated by spaces upon interpolation:
@rocks = qw{ flintstone slate rubble };
print "quartz @rocks limestone\n"; # prints five rocks separated by spaces
There are no extra spaces added before or after an interpolated array; if you want those, you’ll have to put them in yourself:
print "Three rocks are: @rocks.\n";
print "There's nothing in the parens (@empty) here.\n";
emails in perl:
$email = "fred\@bedrock.edu"; # Correct
$email = 'fred@bedrock.edu'; # Another way to do that
A single element of an array will be replaced by its value, just as you’d expect:
@fred = qw(hello dolly);
$y = 2;
$x = "This is $fred[1]'s place"; # "This is dolly's place"
$x = "This is $fred[$y−1]'s place"; # same thing
Note that the index expression is evaluated as an ordinary expression, as if it were outside a string. It is not variable-interpolated first. In other words, if $y
contains the string "2*4", we’re still talking about element 1, not element 7, because "24" as a number (the value of $y used in a numeric expression) is just plain 2. If you want to follow a simple scalar variable with a left square bracket, you need to delimit the square bracket so that it isn’t considered part of an array reference, as follows:
@fred = qw(eating rocks is wrong);
$fred = "right"; # we are trying to say "this is right[3]"
print "this is $fred[3]\n"; # prints "wrong" using $fred[3]
print "this is ${fred}[3]\n"; # prints "right" (protected by braces)
print "this is $fred"."[3]\n"; # right again (different string)
print "this is $fred$$!3]\n"; # right again (backslash hides it)
The foreach Control Structure
foreach $rock (qw/ bedrock slate lava /) {
print "One rock is $rock.\n"; # Prints names of three rocks
}
The control variable is not a copy of the list element—it actually is the list element. That is, if you modify the control variable inside the loop, you’ll be modifying the element itself, as shown in the following code snippet.
@rocks = qw/ bedrock slate lava /;
foreach $rock (@rocks) {
$rock = "\t$rock"; # put a tab in front of each element of @rocks
$rock .= "\n"; # put a newline on the end of each
}
print "The rocks are:\n", @rocks; # Each one is indented, on its own line
What is the value of the control variable after the loop has finished? It’s the same as it was before the loop started. Perl automatically saves and restores the value of the con- trol variable of a foreach loop. While the loop is running, there’s no way to access or alter that saved value. So after the loop is done, the variable has the value it had before the loop, or undef if it hadn’t had a value. That means that if you want to name your loop control variable $rock, you don’t have to worry that maybe you’ve already used that name for another variable.
Perl’s Favorite Default: $_
If you omit the control variable from the beginning of the foreach loop, Perl uses its favorite default variable, $_
. This is (mostly) just like any other scalar variable, except for its unusual name. For example:
foreach (1..10) { # Uses $_ by default
print "I can count to $_!\n";
}
other examples:
$_ = "Yabba dabba doo\n";
print; # prints $_ by default
The reverse
Operator
The reverse
operator takes a list of values (which may come from an array) and returns the list in the opposite order. So if you were disappointed that the range operator, .., only counts upward, this is the way to fix it:
@fred = 6..10;
@barney = reverse (@fred); # gets 10, 9, 8, 7, 6
@wilma = reverse 6..10; # gets the same thing, without the other array
@fred = reverse @fred; # puts the result back into the original array
print "\@fred is @fred";
Remember that reverse
returns the reversed list; it doesn’t affect its arguments. If the return value isn’t assigned anywhere, it’s useless:
reverse @fred; # WRONG - doesn't change @fred
@fred = reverse @fred; # that's better
The sort
Operator
The sort
operator takes a list of values (which may come from an array) and sorts them in the internal character ordering.
@rocks = qw/bedrock slate rubble granite/;
@sorted = sort @rocks; # gets bedrock granite rubble slate
@back = reverse sort @rocks; # get from slate to bedrock
@rocks = sort @rocks; # puts sorted result back into @rocks
@numbers = sort 97..102; # gets 100, 101, 102, 97, 98, 99
like what happened with reverse, the arguments themselves aren’t affected. If you want to sort an array, you must store the result back into that array:
sort @rocks; # WRONG, doesn't modify @rocks
@rocks = sort @rocks; # Now the rock collection is in order
Scalar and List Context
Expressions in Perl always return the appropriate value for their context. For example, take the “name” of an array. In a list context, it gives the list of elements. But in a scalar context, it returns the number of elements in the array:
@people = qw( fred barney betty);
@sorted = sort @people; # list context: barney, betty, fred
$number = 42 + @people; # scalar context: 42 + 3 gives 45
Some expressions don’t have a scalar-context value at all. For example, what should sort
return in a scalar context? You wouldn’t need to sort a list to count its elements, so until someone implements something else, sort
in a scalar context always returns undef
. Another example is reverse
. In a list context, it gives a reversed list. In a scalar context, it returns a reversed string (or reversing the result of concatenating all the strings of a list, if given one):
@backwards = reverse qw/ yabba dabba doo /; # gives doo, dabba, yabba
$backwards = reverse qw/ yabba dabba doo /; # gives oodabbadabbay
Using scalar-Producing Expressions in List Context
Going this direction is straightforward: if an expression doesn’t normally have a list value, the scalar value is automatically promoted to make a one-element list:
@fred = 6 * 7; # gets the one-element list (42)
@barney = "hello" . ' ' . "world";
Well, there's one possible catch:
@wilma = undef; # OOPS! Gets the one-element list (undef), which is not the same as this:
@betty = (); # A correct way to empty an array
Since undef
is a scalar value, assigning undef
to an array doesn't clear the array. The better way to do that is to assign an empty list.
Forcing Scalar Context
On occasion, you may need to force scalar context where Perl is expecting a list. In that case, you can use the fake function scalar. It’s not a true function because it just tells Perl to provide a scalar context:
@rocks = qw( talc quartz jade obsidian );
print "How many rocks do you have?\n";
print "I have ", @rocks, " rocks!\n"; # WRONG, prints names of rocks
print "I have ", scalar @rocks, " rocks!\n"; # Correct, gives a number
Oddly enough, there’s no corresponding function to force list context. It turns out you never need it. Trust us on this, too.
in List Context
One previously seen operator that returns a different value in an array context is the line-input operator,
@lines = <STDIN>; # read standard input in list context
When the input is coming from a file, this will read the rest of the file. But how can there be an end-of-file when the input comes from the keyboard? On Unix and similar systems, including Linux and Mac OS X, you’ll normally type a Control-D
to indicate to the system that there’s no more input; the special character itself is never seen by Perl, even though it may be echoed to the screen. On DOS/Windows systems, use Control-Z instead.
if you give chomp an array holding a list of lines, it will remove the newlines from each item in the list. For example:
chomp(@lines = <STDIN>); # read the lines, not the newlines