Arrays & Lists

Perl Fundamentals — Arrays & Lists
Perl Fundamentals
Course 1 · Chapter 3 · Arrays & Lists

📚 Arrays & Lists

This chapter introduces one of Perl's most distinctive, initially confusing ideas early on purpose: context. The same array can mean "all its elements" or "how many elements it has" depending entirely on how it's used — arrays are the clearest first place to see this, and it colors nearly everything later in the language.

🏷️ The @ Sigil

my @fruits = ("apple", "banana", "cherry");

@ marks an array — "more than one scalar, in order." But watch the sigil when accessing a single element:

say $fruits[0]; # apple — note: $, not @!
⚠ The Sigil Changes When You Access One Element

This trips up nearly everyone coming from another language: @fruits is the array, but $fruits[0] — a single element out of it — uses $, not @. This isn't inconsistent; it's the same rule from Chapter 2 applied precisely: the sigil describes what you're asking for. $fruits[0] asks for one scalar (found inside the array called fruits); @fruits asks for the whole array. The variable's underlying name is always fruits — only the sigil in front changes to match what you're requesting.

🛠️ Common Array Operations

push(@fruits, "date"); # add to the end my $last = pop(@fruits); # remove and return the last element unshift(@fruits, "apricot"); # add to the beginning my $first = shift(@fruits); # remove and return the first element say scalar(@fruits); # the number of elements — forces scalar context (see below) say $fruits[-1]; # the LAST element — negative indices count from the end

🔁 Iterating Arrays

foreach my $fruit (@fruits) { say $fruit; } # index-based, when you need the position too: for my $i (0..$#fruits) { say "$i: $fruits[$i]"; }

$#fruits is the index of the last element of @fruits (not the count — one less than that) — 0..$#fruits is the idiomatic range covering every valid index.

🎭 List vs. Scalar Context

The same array, written identically, behaves differently depending on the context it's evaluated in:

my @fruits = ("apple", "banana", "cherry"); my @copy = @fruits; # LIST context — @copy gets all 3 elements my $count = @fruits; # SCALAR context — $count gets 3, the COUNT

Assigning to an array (@copy = ...) puts the right-hand side in list context — Perl treats @fruits as "all of its elements." Assigning to a scalar ($count = ...) puts it in scalar context — Perl treats the exact same @fruits as "how many elements does this have." Nothing about @fruits itself changed; only what surrounds it did.

💡 This Is the Beginning of a Bigger Idea

Context isn't unique to arrays — it runs through much of Perl (Course 2's Context Deep Dive chapter covers it far more rigorously, including how your own subroutines can detect and respond to it). Arrays are simply the earliest, clearest place to encounter it: the exact same expression, two different meanings, decided entirely by what's asking for the value.

✂️ Array Slices

my @first_two = @fruits[0,1]; # a SLICE — note the @ sigil, since the result is a list say "@first_two"; # apple banana

A slice pulls out multiple elements at once — and because the result is itself a list, the sigil is @, not $, even though it's written with square brackets like a single-element access.

🔀 Sorting and Reversing

my @words = sort @fruits; # alphabetical (default: string comparison) my @backwards = reverse @fruits; my @numbers = (10, 2, 33); say "@{[ sort @numbers ]}"; # 10 2 33 — WRONG if you wanted numeric order! say "@{[ sort { $a <=> $b } @numbers ]}"; # 2 10 33 — correct numeric sort
⚠ sort Defaults to String Order, Not Numeric

This is the single most common Perl gotcha for beginners: sort @numbers compares elements as strings by default — "10" sorts before "2" because "1" is a "smaller" character than "2", exactly like sorting words alphabetically. For actual numeric order, pass a comparator block explicitly: sort { $a <=> $b } @numbers. <=> (sometimes called the "spaceship operator") is the numeric comparison Perl needs here — the default string comparator uses cmp instead.

Arrays: Perl vs. Python

Perl arrays and Python lists cover similar ground — ordered, growable collections with push/pop-style operations on both sides. The real differences are Perl-specific: the sigil switches from @ to $ the moment you access a single element, and the same array genuinely evaluates differently depending on list vs. scalar context — Python's len(my_list) is an explicit function call with no equivalent ambiguity, where Perl's my $count = @array; relies entirely on context to mean "count."

@ vs $

@array is the whole array; $array[0] is one scalar element.

push/pop/shift/unshift

Add/remove from the end or beginning.

List vs. scalar context

The same array means "all elements" or "count," depending on what surrounds it.

sort's default is string order

Use sort { $a <=> $b } @nums for numeric sorting.

💻 Coding Challenges

Challenge 1: Build and Access an Array

Declare an array of 4 favorite foods. Print the first and last elements using $array[0] and negative indexing, and print the total count using scalar(@array).

→ Solution

Challenge 2: List Context vs Scalar Context

Given my @nums = (1, 2, 3, 4, 5);, write one line assigning @nums to a new array (list context) and one line assigning it to a scalar (scalar context). Print both results and explain in one sentence why they differ.

→ Solution

Challenge 3: Numeric Sort

Given my @scores = (85, 9, 100, 42);, print the result of a plain sort @scores (demonstrating the string-sort gotcha), then print the correct numeric sort using a comparator block.

→ Solution

🎯 What's Next

Next chapter: Hashes — the % sigil, key-value operations, and iterating hashes.