Introduction to References
Shlomi Fish
Introduction
Perl allows one to refer to the location of a certain variable in memory. An
expression that holds such location is called a reference. Those that
are familiar with C’s or Pascal’s pointers may think of references as
pointers. There are however, two fundamental differences:
There is no reference arithmetics in perl. If for example, a reference points
to the fifth element of an array, then adding 1 to it will not refer you to the
sixth element. In fact, adding or substracting integers from references is
possible but quite meaningless.
A reference is guaranteed to remain the same even if an array or a string are
resized. In C, reallocing an array yields a completely different pointer.
Perl distinguishes between an array or a hash and a reference of it.
The reference of any array may be taken, and a reference to an array
may always be converted to its elements, but there is still a difference
in functionality.
The best way to change a variable in a different scope
(such as inside a different function) is to pass its reference to the
function. The called function can then dereference the variable to access
or modify its value.
Example: The Towers of Hanoi
In this example, which is intended to give a taste of the capabilities of
references, we will solve the well-known
Towers of Hanoi
problem. The number
of disks can be inputted from the command-line. The towers themselves will
be represented as an array of three elements, each of which is a reference
to an array.
Here goes:
\ – taking a reference to an existing variable
In Perl the backslash (\
) serves as an operator that return the
reference to an existing variable. It can also return a dynamic reference
to a constant.
Here is an example that uses a reference to update a sum:
As can be seen, because the reference to $sum
was used, its value
changes throughout the program.
[ @array ] – a dynamic reference to an array
An array surrounded by square brackets ([ @array ]
) returns a dynamic
reference to an array. This reference does not affect other values directly, which is
why it is called dynamic.
We have already encountered such dynamic array references in the Hanoi
example. But their use is not limited to such. Since a reference to an array
is a scalar, it can serve as a hash value and therefore serve as an object
member. (as will be seen later in the series).
In this example, a function is given two arrays, and returns an array that
is the element-wise sum of both of them:
This code produces the following output:
Note
The fundamental difference between using \@myarray
on an existing
variable named @myarray
to using [ @myarray ]
is this: the latter
forms creates a dynamic copy of @myarray
and if this copy changes,
@myarray
will not change with it. On the other hand, changes made to
a reference generated by backslash, will affect the original variable.
Note that if the members of @myarray
are themselves references, then
the second form will not make a copy of them. Thus, they can be modified too,
even in the second form.
{ %hash } – a dynamic reference to a hash
In a similar way to the square brackets, putting a hash inside a pair
of curly brackets ({ ... }
) will make it into a reference to a
hash. Like an array reference, this reference is a scalar and can be
used as an array element or a hash value. Plus, its own values can be
references to other arrays or hashes.
To demonstrate this let’s see the code of part of the contents table of
this very lecture, to demonstrate the multi-level data structure
capabilities of perl:
Dereferencing
The entire scalar or data structure pointed to by the reference can be
retrieved by dereferncing. Dereferencing is done by using a $
,
a @
or a %
(depending if the reference refers to a scalar
, array or a hash respectively), and then the reference inside curly brackets.
Here are some simple examples:
If the expression that yields the reference is a simple one than the curly
brackets can be omitted (e.g: @$array_ref
or $$ref
).
However, assuming you use curly brackets – the expression surrounded
inside them can be as complex as you would like.