Skip to content
VLSI Mentor

Perl Part I · Module 7 · References

ref(): Asking What a Reference Points To

This function has been used throughout the module as a label in output and as the dispatch key in Chapter 7.10's walker, always with a note that it gets a chapter of its own. Here it is. ref() takes any scalar and tells you what kind of reference it holds, returning a short string — or the empty string if it is not a reference at all, which makes it the natural way to ask that question too. The complete list of answers is short enough to learn in one sitting, and there are two details in it worth knowing before you write a comparison against one: a reference to a reference has its own answer that is not the one people guess, and exactly one of the answers is not in capital letters.

Intermediate15 min readPerlPart IReferencesData Structures

Part I · Module 7 · Chapter 7.14 · ref(): Asking What a Reference Points To

1. Every Answer

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

my @a = (1); my %h = (k=>1); my $s = 5;
sub f { 1 }

my $aref = \@a;
my $rr   = \$aref;

my @things = (
    [ "\\\@a",        \@a        ],
    [ "\\%h",         \%h        ],
    [ "\\\$s",        \$s        ],
    [ "\\&f",         \&f        ],
    [ "[1,2]",        [1,2]      ],
    [ "{k=>1}",       {k=>1}     ],
    [ "sub {}",       sub {}     ],
    [ "\\\$aref",     $rr        ],
    [ "qr/x/",        qr/x/      ],
    [ "plain string", "hello"    ],
    [ "plain number", 42         ],
);

for my $t (@things) {
    my ($label, $val) = @$t;
    my $r = ref($val);
    printf "%-14s ref() = %s\n", $label, ($r eq "" ? "(empty string)" : $r);
}

printf "\nref() is FALSE for a non-reference : %s\n", (ref("hello") ? "true" : "false");
printf "ref() is TRUE  for a reference      : %s\n", (ref([])      ? "true" : "false");
Azvya Education Pvt. Ltd.VLSI Mentor
Captured output
\@a            ref() = ARRAY
\%h            ref() = HASH
\$s            ref() = SCALAR
\&f            ref() = CODE
[1,2]          ref() = ARRAY
{k=>1}         ref() = HASH
sub {}         ref() = CODE
\$aref         ref() = REF
qr/x/          ref() = Regexp
plain string   ref() = (empty string)
plain number   ref() = (empty string)

ref() is FALSE for a non-reference : false
ref() is TRUE  for a reference      : true

The whole table in one run. Six things to take from it.

The four kinds agree with how they were made. \@a and [1,2] both give ARRAY; \%h and {k=>1} both give HASH; \&f and sub {} both give CODE. ref() reports what the reference points to, not how you wrote it.

A non-reference gives the empty string, not undef and not an error. And the empty string is false, which is the next point.

if (ref $x) is the idiomatic "is this a reference". No comparison needed — the empty string is false and every kind name is a non-empty, true string.

REF is a reference to a reference. Not SCALAR, which is what most people guess. Chapter 7.2 §6 measured this; it means you have one more level of dereferencing to do than you thought.

SCALAR is a reference to an ordinary scalar. \$s where $s holds 5.

Regexp is not in capitals. Every other answer is all-caps. §3 is about why that matters.

2. Using It

Is this a reference at all?

Azvya Education Pvt. Ltd.VLSI Mentor
The idiom
if (ref $value) {
    # it refers to something
}
else {
    # it is a plain string or number
}

This is the shape to use. defined ref $value is always true, and ref($value) ne "" works but says less clearly what you mean.

Is it the right kind?

Azvya Education Pvt. Ltd.VLSI Mentor
Validating before you dereference
sub summarise {
    my ($rows) = @_;

    die "summarise needs an array reference, got " .
        (ref($rows) || "a plain value") . "\n"
        unless ref $rows eq "ARRAY";

    return scalar @$rows;
}

Called once with an array reference and then, inside eval, with a hash reference and a plain string:

Azvya Education Pvt. Ltd.VLSI Mentor
Captured output
3 rows
caught: summarise needs an array reference, got HASH
caught: summarise needs an array reference, got a plain value

That check turns Chapter 7.3 §7's Not an ARRAY reference — which names the line inside your function — into a message that names the function's own contract. For a subroutine that other people call, it is three lines well spent.

Note ref($rows) || "a plain value" uses || deliberately: the empty string is exactly what we want to replace, and it is false. This is one of the few places in the module where || is correct and // would be wrong, since the empty string is defined.

3. The Regexp Exception

Azvya Education Pvt. Ltd.VLSI Mentor
regexp-case.pl
use strict;
use warnings;

my $re = qr/clk/;

printf "ref()          : %s\n", ref($re);
printf "eq 'Regexp'    : %s\n", (ref($re) eq "Regexp" ? "matches" : "no match");
printf "eq 'REGEXP'    : %s\n", (ref($re) eq "REGEXP" ? "matches" : "no match");
printf "is it true?    : %s\n", (ref($re) ? "true" : "false");
Azvya Education Pvt. Ltd.VLSI Mentor
Captured output
ref()          : Regexp
eq 'Regexp'    : matches
eq 'REGEXP'    : no match
is it true?    : true

Regexp, not REGEXP. A comparison against the all-caps spelling fails, and it fails silently — no warning, because comparing two strings with eq is a perfectly legitimate thing to do. The only symptom is a branch that never runs.

Since every other answer ref() can give is all-caps, the natural assumption is that this one is too. If you are writing a dispatch on ref() that needs to recognise a compiled regex, that is the one entry to get right:

Azvya Education Pvt. Ltd.VLSI Mentor
A dispatch that handles all of them
my $kind = ref $node;
if    ($kind eq "HASH")   { ... }
elsif ($kind eq "ARRAY")  { ... }
elsif ($kind eq "CODE")   { ... }
elsif ($kind eq "Regexp") { ... }
elsif ($kind eq "")       { ... }       # a plain value
else                      { ... }       # REF, SCALAR, or an object

Compiled regexes turn up in configuration structures more often than you would expect — a list of patterns to match against net names, for instance — which is exactly where a walker meets one.

4. Blessed Objects, Briefly

ref() has one more behaviour worth knowing about even though object-oriented Perl is outside Part I.

When a reference has been blessed into a package — the mechanism Perl objects are built from — ref() returns the package name instead of the underlying kind:

Azvya Education Pvt. Ltd.VLSI Mentor
blessed.pl
use strict;
use warnings;
use Scalar::Util qw(blessed reftype);

my $plain   = { slack => -0.12 };
my $blessed = bless { slack => -0.12 }, 'Timing::Record';

printf "plain   : ref=%-15s blessed=%-15s reftype=%s\n",
    ref($plain), (blessed($plain) // "(not blessed)"), reftype($plain);
printf "blessed : ref=%-15s blessed=%-15s reftype=%s\n",
    ref($blessed), (blessed($blessed) // "(not blessed)"), reftype($blessed);

printf "ref eq HASH rejects the object : %s\n",
    (ref($blessed) eq "HASH" ? "no, accepted" : "yes, rejected");
Azvya Education Pvt. Ltd.VLSI Mentor
Captured output
plain   : ref=HASH            blessed=(not blessed)   reftype=HASH
blessed : ref=Timing::Record  blessed=Timing::Record  reftype=HASH
ref eq HASH rejects the object : yes, rejected

Both are hash references underneath. ref() reports HASH for one and Timing::Record for the other.

The consequence for the code in this module: ref($x) eq "HASH" is false for a blessed hash reference. A walker that dispatches on ref() will send an object to its else branch, which is why Chapter 7.10's walker has one and reports what it found rather than ignoring it.

Scalar::Util — core Perl, nothing to install — gives you the two questions separately:

QuestionFunction
what kind of container is it really?reftype($x) — HASH for both
is it an object, and of what class?blessed($x) — the package, or undef

For Part I purposes the practical rule is short: if your data might contain objects, dispatch on reftype() rather than ref() when you care about the container, and use blessed() when you care about the class. Everything in Modules 1 to 14 works with plain references, where ref() and reftype() agree.

5. Why This Matters in Engineering Work

It is how you validate an argument. A subroutine that takes a structure and checks ref $arg eq "ARRAY" before dereferencing fails with a message about its own contract rather than a Not an ARRAY reference deep inside it. On a utility that several scripts call, that is the difference between a five-second fix and a bisect.

It is how a generic walker works. Every inspection, validation or conversion routine that handles data of unknown shape dispatches on ref(). Chapter 7.10 is that pattern in full.

And the two gotchas are both silent. == instead of eq gives a check that always passes; "REGEXP" instead of "Regexp" gives a branch that never runs. Neither produces an error, and one produces no warning at all. They are worth knowing once rather than finding twice.

6. Common Mistakes

ref($x) == "ARRAY". Numeric comparison; true for everything. Use eq.

"REGEXP" instead of "Regexp". Silently never matches.

Expecting SCALAR for a reference to a reference. That is REF.

Expecting undef for a non-reference. It is the empty string, which is defined and false.

ref($x) // "plain". The empty string is defined, so // does not replace it. Use || here.

ref($x) eq "HASH" on a blessed hash reference. That returns the class name. Use reftype().

Omitting an else in a ref() dispatch. REF, SCALAR, Regexp and objects all fall through it.

7. Exercise

Exercise 1 — the whole table. Reproduce §1's eleven cases and record every answer. Confirm that the two ways of making each kind agree.

Exercise 2 — the empty string. Print ref("hello") inside brackets so you can see it is empty, then test whether it is defined and whether it is true. Say which of those two makes if (ref $x) work.

Exercise 3 — REF. Build a reference to an array reference. Print ref() at both levels, then reach the array's element count through both. Say why SCALAR would have been a reasonable guess and what it would have implied.

Exercise 4 — validation. Write a subroutine that requires an array reference and dies with a message naming what it got instead. Call it three times: with an array reference, a hash reference, and a plain string. Record all three results.

Exercise 5 — the == trap. Write if (ref($x) == "ARRAY") and call it with a hash reference. Record whether the branch was taken and what reached STDERR. Then fix it to eq and confirm the branch is now correctly skipped.

Exercise 6 — the case trap. Build qr/clk/ and compare ref() against both "Regexp" and "REGEXP". Record both results and confirm nothing reached STDERR for the failing one.

Exercise 7 — blessed. Build a plain hash reference and a blessed one. Print ref, blessed and reftype for each. Then write a ref($x) eq "HASH" test and confirm it rejects the blessed one.

Exercise 8 — a complete dispatch. Write a dispatch covering HASH, ARRAY, CODE, Regexp, the empty string, and an else. Feed it one value of each kind plus a REF and a blessed reference, and confirm every input lands in exactly one branch.

8. Summary

  • ref() returns ARRAY, HASH, SCALAR, CODE, REF or Regexp for a reference, and the empty string for anything that is not one.
  • if (ref $x) is the idiomatic test for "is this a reference" — the empty string is false.
  • How you made the reference does not matter. \@a and [1,2] both give ARRAY.
  • A reference to a reference is REF, not SCALAR.
  • Regexp is the only answer that is not all-caps, and a comparison against "REGEXP" fails silently.
  • Compare with eq, never ==. Numeric comparison converts both strings to 0 and the test always passes; it warns but does not fail.
  • Use || and not // to supply a label for the empty string — the empty string is defined.
  • A blessed reference returns its class name, so ref($x) eq "HASH" rejects an object. reftype() gives the container, blessed() gives the class; both are in core Scalar::Util.
  • Always include an else in a ref() dispatch.

9. The Module, Closed

References are what make Perl's data structures possible, and the module has been one argument built in fourteen steps.

The mechanism is small: a scalar can hold a reference to a container, and scalars do not flatten. Chapter 7.1 established that, and everything since has been consequences of it. \ takes one; [ ] and { } build one in a single step; the arrow reaches through one; and because the inner containers are reached indirectly, structures nest to any depth.

The shapes you will actually use are four, and three of them are in Chapter 7.5 §4, Chapter 7.7 and Chapter 7.8: a list of records, a named list per key, and records keyed by name. The fourth, an array of arrays, is Chapter 7.6's table. Almost every parsed tool report is one of those four.

The traps are worth collecting in one place, because they are the module's real content and they share a property — none of them produces an error:

  • @$r[0] is a one-element slice, not an element, and never warns.
  • exists $h{a}{b} creates $h{a}, so a question changes the data.
  • A misspelled key in a foreach gives zero iterations and exit 0.
  • push @table, \@fields with the declaration outside the loop makes every row identical.
  • A shallow copy shares the inner containers, so a "copy" follows changes at depth.
  • ref($x) == "ARRAY" is true for everything.
  • "REGEXP" never matches.

What they have in common is that the program keeps running and reports success. That is why this module measured so much rather than asserting it, and it is the habit worth taking forward: when nested data gives a surprising answer, check what the structure actually contains — one Dumper call, or one ref() — before assuming the logic around it is wrong.

Module 8 moves from data to control: conditionals and the forms Perl offers for expressing them.

Where this fits

Part of the Perl curriculum.