Reference in Perl

Introduction

References are the most important feature of Perl which helps in creating complex data structures. This tutorial is aimed for a complete newbie in Perl. We will start with What references are? What are their benefits? How to use them? Their syntax and examples. Wasting no more time just dive into it!

What is a reference?

If you are familiar with C language then you can consider a reference as a pointer (not literally, because there are no pointers in Perl like C language). A variable can store a reference to some variable/value/array or hash.

Reference to a variable

+----------\\       +----------\\
|     x     >      |     y     >
+----------/       +----------/
      |                  |
+-----------+      +-----------+
|     O-----+----->|   54321   |
+-----------+      +-----------+

Here the variable $x has a reference which points to the value of variable $y (which is 54321).

To create a reference to a value we use the backslash operator (\\). For example:

#!/usr/bin/perl
use warnings;
my $y = 54321;
my $x = \$y;     # $x is a reference to the value of variable $y.
print "$y\n";    # 54321
print "$x\n";    # will print the address where the value 54321 is stored like SCALAR(0x13dcac0)
print "${$x}\n"; # 54321 (dereferencing a scalar variable)
print "$$x";     # 54321 (same as above)

Reference to an array

@a		@{$aref}		# An array
reverse @a	reverse @{$aref}	# Reverse the array
$a[3]		${$aref}[3]		# An element of the array
$a[3] = 17;	${$aref}[3] = 17	# Assigning an element
+----------\\
|     x     >      +----------\\
+----------/       |     y     >
      |            +----------/
+-----------+            |
|     O-----+----->+###########+
+-----------+      +"""""""""""+
                   |    Foo    |
+----------\\       +-----------+
|     z     >      |    ABC    |
+----------/       +-----------+
      |            |    BUZ    |
+-----------+      +-----------+
|     O-----+----->|    VIZ    |
+-----------+      +-----------+

Here the refernce $x is pointing to the array @y, reference $z is pointing to the 4th element of array @y i.e. $y[4].

#!/usr/bin/perl
use warnings;
my @y = ("Foo", "ABC", "BUZ", "VIZ");
my $x = \\@y;         # creating reference of an array
print "$x\\n";        # ARRAY(0x189faf0)
print "@y\\n";        # Foo ABC BUZ VIZ
print "@{$x}\\n";     # Foo ABC BUZ VIZ (dereferencing)
print "@$x\\n";       # Foo ABC BUZ VIZ (You may omit curly brace here)
print "${$x}[1]\\n";  # ABC  (Accessing element at position 1 of array using reference variable)
print "$$x[1]\\n";    # ABC  (Another way of doing the same)
print "$x->[1]";     # ABC  (You can use -> operator too)

Reference to a hash

You can make a reference to hash in the similar way as you created from scalar variables and array.

%h		%{$href}	      # A hash
keys %h		keys %{$href}	      # Get the keys from the hash
$h{'red'}	${$href}{'red'}	      # An element of the hash
$h{'red'} = 17	${$href}{'red'} = 17  # Assigning an element

Loop over an array or hash using reference

If you want to loop over an array then

for my $element (@array) {
           ...
}

If you want to loop over an array using reference then

for my $element (@{$aref}) {
           ...
}

If you want to loop over a hash then

for my $key (keys %hash) {
          print "$key -> $hash{$key}\\n";
}

If you want to loop over a hash using reference then

for my $key (keys %{$href}) {
          print "$key => ${$href}{$key}\\n";
}

Tip

${$aref}[3] is too hard to read, so you can write $aref->[3] instead.
${$href}{red} is too hard to read, so you can write $href->{red} instead.

If $aref holds a reference to an array, then $aref->[3] is the fourth element of the array. Don’t confuse this with $aref[3], which is the fourth element of a totally different array, one deceptively named @aref. $aref and @aref are unrelated the same way that $item and @item are.

Similarly, $href->{‘red’} is part of the hash referred to by the scalar variable $href, perhaps even one with no name. $href{‘red’} is part of the deceptively named %href hash.

It’s easy to forget to leave out the ->, and if you do, you’ll get bizarre results when your program gets array and hash elements out of totally unexpected hashes and arrays that weren’t the ones you wanted to use.

 
With the help of references you can construct complex datastructures as:

1) A reference to a list containing references to several lists

+----------\\
|     x     >                      +-->+###########+
+----------/                       |   +"""""""""""+
      |                            |   |    Foo    |
+-----------+                      |   +-----------+
|     O-----+----->+###########+   |   |    ABC    |
+-----------+      +"""""""""""+   |   +-----------+
                   |     O-----+---+
                   +-----------+
                   |     O-----+------>+###########+
                   +-----------+       +"""""""""""+
                   |     O-----+---+   |    BUZ    |
                   +-----------+   |   +-----------+
                                   |   |    VIZ    |
                                   |   +-----------+
                                   |
                                   |
                                   +-->+###########+
                                       +"""""""""""+
                                       |    BUZ    |
                                       +-----------+

2) A hash containing references to lists

+----------\\
|     x     >                 +-->+###########+
+----------/                  |   +"""""""""""+
      |                       |   |    Foo    |
+#########################+   |   +-----------+
+"""""""""""""""""""""""""+   |   |    ABC    |
+-----------\\ +-----------+   |   +-----------+
|    aaa     >|     O-----+---+
+-----------< +-----------+
|    bbb     >|     O-----+------>+###########+
+-----------< +-----------+       +"""""""""""+
|    ccc     >|     O-----+---+   |    BUZ    |
+-----------/ +-----------+   |   +-----------+
                              |   |    VIZ    |
                              |   +-----------+
                              |
                              |
                              +-->+###########+
                                  +"""""""""""+
                                  |    BUZ    |
                                  +-----------+

Creating reference to an anonymous array

To create an anonymous array [ ] brackets are used. For example:

$x = [1, 2, 3];

Here $x is a reference to an anonymous array.

Creating reference to an anonymous hash

To create an anonymous hash curly braces { } are used. For example:

$x = {Name => 'Chankey', Email => 'chankey007@gmail.com'};

Creating reference to an anonymous subroutine

For this just assign subroutine to a scalar variable (reference variable in our case).

$x = sub { print "Welcome to Linux Stall\n" };

Some notations

Consider the example given below

@a = ( [1, 2, 3],
               [4, 5, 6],
	       [7, 8, 9]
);

@a is an array with three elements, and each one is a reference to another array. $a[1] is one of these references. It refers to an array, the array containing (4, 5, 6), and because it is a reference to an array, we can write $a[1]->[2] to get the third element from that array. $a[1]->[2] is the 6. Similarly, $a[0]->[1] is the 2. What we have here is like a two-dimensional array; you can write $a[ROW]->[COLUMN] to get or set the element in any row and any column of the array.

The notation still looks a little cumbersome, so there’s one more abbreviation:

In between two subscripts, the arrow is optional i.e. instead of $a[1]->[2], we can write $a[1][2]; it means the same thing. Instead of $a[0]->[1] = 23, we can write $a[0][1] = 23 ; it means the same thing. Now it really looks like two-dimensional arrays! You can see why the arrows are important. Without them, we would have had to write ${$a[1]}[2] instead of $a[1][2]. For three-dimensional arrays, they let us write $x[2][3][5] instead of the unreadable ${${$x[2]}[3]}[5].

This is all what a newbie should know about reference in Perl.

About the author

Chankey Pathak is the founder of Linux Stall. He is a Perl developer at Wokana Technologies. He is a Linux and Perl enthusiast. Check out his latest website on Tech News. You may follow him on Google+.