Perl Part I · Module 7 · References
Why Perl Needs References
Four chapters in the last two modules ran into the same wall from four different directions: a subroutine that could not return two arrays, a hash key that could not hold several values, two hashes that arrived merged, and a list of parsed rows that had to be stored with a construct the chapter could only call a forward pointer. All four are the same limitation, and this chapter explains why it exists and why the fix has only one possible shape. The reason nesting fails is that flattening applies to containers — and the reason the fix works is that a scalar is not a container, so a single value standing in for a whole array survives a list intact. That standing-in value is a reference, and this chapter is the argument for it rather than the syntax.
Intermediate14 min readPerlPart IReferencesData Structures
Part I · Module 7 · Chapter 7.1 · Why Perl Needs References
1. Four Chapters, One Wall
Each of these was measured where it appeared, and each is the same problem:
| Where | What could not be done |
|---|---|
| Chapter 5.12 §3 | A subroutine returned two arrays; the caller received one flat list with no boundary. |
| Chapter 6.3 §3 | A duplicated key could keep only one value, so the earlier row was lost. |
| Chapter 6.10 §5 | Two hashes passed to one subroutine arrived merged, with no way to tell them apart. |
| Chapter 5.8 §3 | Parsed rows had to be stored somehow, and the chapter used \@field while calling it a forward pointer. |
None of them produced a warning. Each produced a plausible result that had quietly lost structure.
The reason is one rule, from Chapter 5.12 §1: a list inside a list is flattened into it, and nothing records that there was ever an inner list. Parentheses group for the parser; they do not create structure.
2. Flattening Applies to Containers
Here is the observation the whole module turns on.
use strict;
use warnings;
my @front = ("a", "b");
my @back = ("c", "d", "e");
my @with_arrays = (@front, @back);
my @with_scalars = ("x", "y");
printf "two arrays in a list : %d element(s)\n", scalar(@with_arrays);
printf "two scalars in a list : %d element(s)\n", scalar(@with_scalars);two arrays in a list : 5 element(s)
two scalars in a list : 2 element(s)Two arrays became five items. Two scalars stayed two.
That is not a coincidence or a special case — it is what flattening means. A list expands any container it finds into that container's elements. A scalar has no elements to expand into, so it contributes exactly itself.
So the question "how do I nest a container" has a precise answer available: do not put a container in the list. Put a scalar in the list, and arrange for that scalar to stand for the container.
3. A Reference Is That Scalar
use strict;
use warnings;
my @front = ("a", "b");
my @back = ("c", "d", "e");
my @flat = (@front, @back);
my @refs = (\@front, \@back);
printf "without references : %d element(s)\n", scalar(@flat);
printf "with references : %d element(s)\n", scalar(@refs);
printf " first points at %d\n", scalar(@{ $refs[0] });
printf " second points at %d\n", scalar(@{ $refs[1] });without references : 5 element(s)
with references : 2 element(s)
first points at 2
second points at 3Two elements, and each one still knows its own length.
\@front is a reference — a single scalar value that refers to the array @front. Because it is a scalar, it does not flatten; because it refers to the array, nothing is lost.
The two pieces of syntax used here get their own chapters:
\@fronttakes a reference. Chapter 7.2 covers it.@{ $refs[0] }gets the array back from a reference. Chapter 7.3 covers it, and Chapter 7.4 covers the shorter form you will actually write.
For this chapter they are the minimum needed to show that the idea works.
4. The Fork, Drawn
What you put in the list decides whether nesting survives
5. What a Reference Looks Like
use strict;
use warnings;
my @marks = (72, 65, 90);
my $ref = \@marks;
print "the reference : $ref\n";the reference : ARRAY(0x938c33858)
the reference : ARRAY(0xa64c33858)A reference printed shows what kind of thing it refers to and an address — not the contents. The hexadecimal number is where the array lives in memory, and the two runs above show it differing, which is why a reference is something to follow rather than something to print. Its printed length is not fixed either, since the address can be wider or narrower.
Chapter 7.2 covers the four kinds you will meet, and Chapter 7.12 covers the tool that prints a structure's contents for debugging, which is what you actually want when inspecting one.
6. A Reference Is Always True
This is the first bug people write with references, so it is worth meeting before any syntax.
use strict;
use warnings;
my @empty = ();
my $ref = \@empty;
printf "the array : %s\n", (@empty ? "true" : "false");
printf "the reference: %s\n", ($ref ? "true" : "false");the array : false
the reference: trueThe array is empty, so it is false — Chapter 5.7 §3's idiom. The reference to it is true.
That is correct and it is not a quirk: a reference is a real value, so it is true for the same reason any non-empty string is true. There is a reference; it just happens to point at nothing much.
7. Why This Matters in Engineering Work
Every real data shape in this trade is nested. A results table is rows of fields. A per-block failure list is several values under one name. A configuration is sections containing settings. A timing report is paths each with several attributes. None of these fit in a flat array or a flat hash, and all of them are two lines of reference syntax away.
The four walls from §1 are the common cases, not exotic ones. Returning two things from a subroutine, keeping several values under one key, passing two structures to one function, storing a list of records — those are ordinary requirements, which is why the index calls this "the module Perl cannot be understood without".
And the alternative is encoding structure into strings, which is what people do before they learn references: joining fields with a separator and splitting them again, or naming keys block_alu_status so the structure lives in the key text. Both work and both are agreements nothing enforces — Chapter 5.12 §3's callout said so. A reference makes the structure real.
8. Common Mistakes
Expecting parentheses to create nesting. They group for the parser only — Chapter 5.12 §1.
Testing if ($aref) to see whether there is any data. That tests whether you have a reference. Test @$aref for the contents.
Printing a reference into a report. You get ARRAY(0x...) and a different address each run.
Encoding structure into key names or delimited strings. It works and nothing enforces it; a reference makes the structure explicit.
Assuming a reference copies the data. It refers to the original — which is Chapter 7.2's subject and the point of Chapter 7.13.
9. Exercise
Exercise 1 — what flattens. Put two arrays into a list and two scalars into another, and report both element counts. Then state in one sentence what the two results have to do with each other.
Exercise 2 — the fix. Build a list of two array references with \, report its element count, and then report the length of each referenced array. Confirm you get 2, then the two original lengths.
Exercise 3 — the four walls. For each of §1's four rows, write one sentence saying what the script was trying to do and what it got instead. Name the chapter each came from.
Exercise 4 — what it looks like. Print a reference to an array and a reference to a hash. Record both, then run the script again and say which part of the output changed.
Exercise 5 — always true. Take a reference to an empty array and print whether the array is true and whether the reference is true. Explain the difference in one sentence.
Exercise 6 — the right test. Write a check that prints has entries only when a reference exists and points at a non-empty array. Test it with a reference to a populated array, a reference to an empty one, and an undef. Confirm all three behave sensibly and none warns.
Exercise 7 — the string workaround. Store two groups of block names in one flat hash by putting the group into the key name, then write the code that lists one group. Say what nothing is enforcing about that arrangement.
10. Summary
- Four earlier chapters hit the same wall: no way to keep two containers distinct inside one list, hash value, return value or argument list.
- The cause is that a list flattens containers — Chapter 5.12 §1 — and nothing records that an inner container existed.
- A scalar does not flatten. Two arrays in a list gave five items; two scalars gave two.
- So nesting is possible only by replacing the inner container with one scalar that stands for it, which is the only shape the fix could have.
- That scalar is a reference, and it prints as a kind plus an address — something to follow, not to display.
- A reference is always true, even to an empty container.
if ($aref)asks whether you have a reference;if (@$aref)asks whether its array has contents. if ($aref && @$aref)asks both, in the safe order.
Chapter 7.2 covers making a reference: the backslash operator, the four kinds of thing you can refer to, and what each one prints as.
Where this fits
Part of the Perl curriculum.
