Skip to content
VLSI Mentor

Perl Part I · Module 7 · References

Making a Reference With \

Taking a reference needs one character: a backslash in front of the variable. What the resulting value does is worth more attention than how to write it. A reference refers to the original rather than copying it, so changing something through the reference changes the variable — which is the behaviour the rest of this module depends on and the one Chapter 7.13 is entirely about. It also keeps the data alive after the variable that named it has gone out of scope, which surprises anyone arriving from a language where that would be a dangling pointer. And there is one piece of syntax that looks like harmless tidying and is not: wrapping the variable in parentheses gives you something completely different from what you asked for.

Intermediate14 min readPerlPart IReferencesData Structures

Part I · Module 7 · Chapter 7.2 · Making a Reference With \

1. One Operator, Four Kinds

Azvya Education Pvt. Ltd.VLSI Mentor
four-kinds.pl
use strict;
use warnings;

my @marks = (72, 65);
my %conf  = (retries => 3);
my $name  = "alu";

sub run { return 1 }

print "\\\@marks : ", \@marks, "\n";
print "\\\%conf  : ", \%conf,  "\n";
print "\\\$name  : ", \$name,  "\n";
print "\\&run   : ", \&run,   "\n";
Azvya Education Pvt. Ltd.VLSI Mentor
Captured output — the addresses differ every run
\@marks : ARRAY(0x940c40858)
\%conf  : HASH(0x940c407b0)
\$name  : SCALAR(0x940c408b8)
\&run   : CODE(0x940c40918)

\ in front of a variable gives a reference to it, and the printed form says what kind of thing it refers to plus an address — not the contents, as Chapter 7.1 §5 established.

You writeYou getUsed for
\@arrayan ARRAY referencenesting arrays — Chapter 7.6
\%hasha HASH referencerecords and nested hashes — Chapter 7.8
\$scalara SCALAR referencepassing a variable to be modified
\&suba CODE referencedispatch tables — Chapter 7.11

The array and hash forms are what you will use constantly. The scalar form is occasional. The code form has one very good use, which Chapter 7.11 covers.

2. A Reference Refers — It Does Not Copy

This is the most important sentence in the chapter.

Azvya Education Pvt. Ltd.VLSI Mentor
not-a-copy.pl
use strict;
use warnings;

my @marks = (72, 65);

my $ref = \@marks;

push @$ref, 90;

printf "via the reference : %d element(s)\n", scalar(@$ref);
printf "the original      : %d element(s)  [%s]\n", scalar(@marks), join(" ", @marks);
Azvya Education Pvt. Ltd.VLSI Mentor
Captured output
via the reference : 3 element(s)
the original      : 3 element(s)  [72 65 90]

push @$ref, 90 added to @marks. There is one array; $ref is another way to reach it.

That is the whole point — it is what makes nesting work, because the structure has to refer to real data rather than to snapshots of it. It is also the behaviour that catches people out when they pass a reference into a subroutine expecting the caller's data to be safe. Chapter 7.13 is the chapter on what gets shared and what does not.

Two references to the same variable are the same reference:

Azvya Education Pvt. Ltd.VLSI Mentor
same-or-different.pl
use strict;
use warnings;

my @a = (1);
my @b = (1);

my $r1 = \@a;
my $r2 = \@a;
my $r3 = \@b;

printf "two refs to \@a      : %s\n", ($r1 == $r2 ? "equal"  : "differ");
printf "refs to \@a and \@b   : %s\n", ($r1 == $r3 ? "equal"  : "differ");
Azvya Education Pvt. Ltd.VLSI Mentor
Captured output
two refs to @a      : equal
refs to @a and @b   : differ

@a and @b hold identical contents and their references differ, because a reference identifies a location, not a value. Comparing references with == therefore asks "are these the same container", which is occasionally exactly what you want to know.

3. A Reference Keeps the Data Alive

Azvya Education Pvt. Ltd.VLSI Mentor
outlives-scope.pl
use strict;
use warnings;

my $ref;

{
    my @inner = ("a", "b", "c");
    $ref = \@inner;
    printf "inside the block : %d element(s)\n", scalar(@$ref);
}

printf "after the block  : %d element(s)  [%s]\n", scalar(@$ref), join(" ", @$ref);
Azvya Education Pvt. Ltd.VLSI Mentor
Captured output — STDOUT
inside the block : 3 element(s)
after the block  : 3 element(s)  [a b c]
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet

@inner was declared inside the block and its name went out of scope at the closing brace — Chapter 2.3's rule. The array itself is still there, with all three elements, because $ref still refers to it.

4. \(@a) Is Not \@a

Here is the trap, and it looks like tidying.

Azvya Education Pvt. Ltd.VLSI Mentor
distributive.pl
use strict;
use warnings;

my @a = (1, 2, 3);

my $one  = \@a;
my @many = \(@a);

printf "\\\@a   : one %s reference\n", ref($one);
printf "\\(\@a) : %d reference(s), each a %s\n", scalar(@many), ref($many[0]);

${ $many[0] } = 99;

printf "after writing through the first : %s\n", join(" ", @a);
Azvya Education Pvt. Ltd.VLSI Mentor
Captured output
\@a   : one ARRAY reference
\(@a) : 3 reference(s), each a SCALAR
after writing through the first : 99 2 3

\@a is one ARRAY reference. \(@a) is three SCALAR references — one per element.

The backslash is distributive over a list: given a list, it returns a list of references, one to each item. (@a) is a list of three elements, so you get three references. And they are real references into the array, which is why writing through the first one changed @a.

5. References to Scalars

Azvya Education Pvt. Ltd.VLSI Mentor
scalar-ref.pl
use strict;
use warnings;

my $count = 5;

my $ref = \$count;

printf "read through  : %d\n", $$ref;

$$ref = 99;

printf "after writing : %d\n", $count;
Azvya Education Pvt. Ltd.VLSI Mentor
Captured output
read through  : 5
after writing : 99

$$ref reaches the scalar — Chapter 7.3 covers the notation. Writing through it changes $count, for the same reason §2's push changed @marks.

The main use is letting a subroutine modify a caller's variable deliberately, which Module 10 covers. It is far less common than array and hash references, and when you see it the question to ask is whether returning a value would be clearer.

A reference to a literal is read-only

Azvya Education Pvt. Ltd.VLSI Mentor
readonly.pl
use strict;
use warnings;

my $ref = \"constant";

printf "read : %s\n", $$ref;

$$ref = "changed";
Azvya Education Pvt. Ltd.VLSI Mentor
Captured output — STDOUT
read : constant
Azvya Education Pvt. Ltd.VLSI Mentor
Captured output — STDERR
Modification of a read-only value attempted at readonly.pl line 8.

Reading works; writing is fatal — the script died at that line and exited 255. A literal has no storage you are allowed to change, and Perl says so rather than silently discarding the write — which is the right behaviour and a rare case of a reference operation failing loudly.

6. A Reference to a Reference

Azvya Education Pvt. Ltd.VLSI Mentor
ref-to-ref.pl
use strict;
use warnings;

my @a = (1, 2);

my $ref    = \@a;
my $refref = \$ref;

printf "\$ref    is a %s reference\n", ref($ref);
printf "\$refref is a %s reference\n", ref($refref);
printf "through both : %d element(s)\n", scalar(@{ $$refref });
Azvya Education Pvt. Ltd.VLSI Mentor
Captured output
$ref    is a ARRAY reference
$refref is a REF reference
through both : 2 element(s)

Note the second line: a reference to a reference reports as REF, not SCALAR. That distinction exists because Perl knows the thing being referred to is itself a reference.

Double references are rare in ordinary scripting. They are worth recognising because ref() returning REF is otherwise a confusing thing to see — and because it tells you you have one more level of dereferencing to do than you thought. Chapter 7.14 covers ref() properly.

7. Why This Matters in Engineering Work

Everything nested starts here. A table of rows is an array of array references; a record is a hash reference; a per-block failure list is a hash of array references. All of them are built from \ or from Chapter 7.5's shorthand.

Passing a large structure costs nothing. A reference is one scalar, so handing a ten-thousand-row table to a subroutine passes one value rather than copying ten thousand. That is the usual reason to pass by reference even when you do not need to modify anything.

And the refer-not-copy behaviour is the thing to be deliberate about. A subroutine given a reference can change the caller's data, and whether that is a feature or a bug depends entirely on what you intended. Saying so in the subroutine's name — normalise_in_place against normalised_copy — is worth the characters, and Chapter 7.13 is the chapter about the version of this that surprises people.

8. Common Mistakes

Expecting a reference to copy. It refers. Changing through it changes the original.

Writing \(@a) for an array reference. That is one scalar reference per element. Use \@a.

Expecting a reference to a local to dangle after its scope. Perl keeps the data alive while any reference exists.

Writing through a reference to a literal. Modification of a read-only value attempted, and fatal.

Reading ref() returning REF as an error. It means a reference to a reference.

Comparing references with eq to test contents. == on references compares locations; neither compares contents.

Printing a reference in a report. You get a kind and an address, different every run.

9. Exercise

Exercise 1 — the four kinds. Take a reference to an array, a hash, a scalar and a subroutine, and print all four. Record which word each printed and say which two you expect to use most.

Exercise 2 — refer, not copy. Take a reference to a three-element array, push through the reference, then print the original's count and contents. State in one sentence how many arrays exist.

Exercise 3 — same or different. Make two references to one array and one to a different array with identical contents. Compare both pairs with == and explain the results using the word "location".

Exercise 4 — outliving scope. Reproduce §3's block. Report the count inside and after, confirm STDERR is empty, and say in one sentence why this is not a dangling pointer.

Exercise 5 — the distributive trap. For a three-element array, create \@a, \(@a) and (\@a). For each, print how many references you got and what kind. Then write through the first element of the distributive version and show the array changed.

Exercise 6 — the read-only literal. Take a reference to a string literal, read through it successfully, then attempt to write. Record the error and the exit status.

Exercise 7 — the double reference. Build a reference to an array reference. Print ref() of each level, then reach the array's element count through both. Say how many dollar signs or braces that needed.

10. Summary

  • \ in front of a variable takes a reference to it — \@a, \%h, \$s, \&f.
  • A reference prints as its kind plus an address — ARRAY(0x…) — not its contents.
  • A reference refers; it does not copy. Changing something through it changes the original variable.
  • Two references to the same variable are == equal; references to two identical-looking variables are not. A reference identifies a location.
  • A reference keeps the data alive past the variable's scope, so returning a reference to a local is safe and there is nothing to free.
  • \(@a) is distributive — one SCALAR reference per element — and is not \@a. Parentheses after a backslash change the meaning.
  • Writing through a reference to a literal is fatal: Modification of a read-only value attempted.
  • A reference to a reference reports as REF.

Chapter 7.3 covers getting the container back out: the sigil-plus-dollar forms, the braced forms, and what happens when you dereference the wrong kind of thing.

Where this fits

Part of the Perl curriculum.