Perl References -- Basic Usage, Subroutines and Complex Data Structures

In Perl, a reference is a scalar (single value) variable that refers to some other variable. A reference may refer to another scalar value, or to an array or a hash or subroutine or whatever.

You can create references by using the backslash operator to get a reference to an existing variable, like this:


# Create a scalar value.
my $a_scalar = "Some text.";

# Create an array
my @an_array = ('apple', 'orange', 'cherry');

# Create a hash
my %a_hash = (
    'animal' => 'bear',
    'plant' => 'oak',
    'fungus' => 'truffle',
);

# Reference to a scalar
my $scalar_ref = $a_scalar;

# Reference to an array
my $array_ref = @an_array;

# Reference to a hash
my $hash_ref = %a_hash;




We can then use these references in place of using the original variables themselves directly. To use a reference to a scalar, just prefix it with an extra $. To use references to hashes or arrays, use the -> operator. A few examples will make things clear.

# Print scalar value
print $a_scalar, "\n";

# Print scalar value using reference
print $$scalar_ref, "\n";

# Print array value
print $an_array[0], "\n";

# Print array value using reference
print $array_ref->[0], "\n";

# Print hash value
print $a_hash{'plant'}, "\n";

# Print hash value using reference
print $hash_ref->{'plant'}, "\n";




Some text.
Some text.
apple
apple
oak
oak






Initializing References Directly



You can also create references to arrays and hashes directly, without the intermediate step of creating a variable to refer to.

my $array_ref = ['one', 'two', 'three'];

my $hash_ref = {
    'fox' => 'animal',
    'rabbit' => 'animal',
    'chalk' => 'mineral',
    'cabbage' => 'vegetable',
};




Using Reference to Create Complex Data Structures



Since references are scalar values, you can use them to create complex data structures.

Array of Arrays



For instance you can create an array of arrays:

# Array of arrays
my @an_array = (
    [1, 2, 3],
    ['hello', 'there'],
    ['foxtrot', 'tango', 'waltz'],
);

print $an_array[1][0];




hello




Array of Hashes



Or an array of hashes:

# Array of hashes
my @an_array = (
    { 1 => 'one', 2 => 'two', 3 => 'three' },
    { 'fox' => 'animal', 'chalk' => 'mineral'},
);

print $an_array[1]->{'fox'};




animal




Passing References to Subroutines and Returning References from Subroutines in Perl



References are particularly handy for passing in arguments to subroutines, or returning values from them. Here are a couple of specific examples, but you can easily generalize to passing any data structure into a subroutine or returning any data structure from a subroutine.

Passing an Array Into a Subroutine in Perl



use strict;
use warnings; 

# A subroutine that prints (displays)
# an array.
sub print_array
{
    # Expect to be passed a reference
    # to an array.
    my $array_ref = shift;
    
    # Print each value of the array.
    # Note that we typecast the reference
    # to an actual array by prefixing it
    # with @.
    foreach my $value(@$array_ref) {
        print "$valuen";
    }
}

sub main
{
    # Declare and initialize an array.
    my @fruits = ('apple', 'orange', 'banana');
    
    # Pass a reference to the array to a function.
    print_array(@fruits);
}

main();




apple
orange
banana





Returning a Hash From a Subroutine in Perl



use strict;
use warnings; 

# A subroutine that returns a hash.
sub get_hash
{
    # Create a hash
    my %a_hash = (
        1 => 'one',
        2 => 'two',
        3 => 'three',
    );
    
    # Return a reference to the hash.
    return %a_hash;
}

sub main
{
    # Get a reference to a hash.
    my $hash_ref = get_hash();
    
    # Iterate through the hash and print
    # the key-value pairs.
    # Note, we typecast the reference to the has
    # to an actual hash be prefixing it with %.
    while( my ($key, $value) = each %$hash_ref ) {
        print "$key = $value\n";
    }
}

main();




1 = one
3 = three
2 = two




Passing References to File Handles to Subroutines in Perl



You can also create references to file handles; then you can pass the file handles to subroutines or even store them in objects if you're doing OO programming.

use strict;
use warnings; 

# A subroutine that writes to
# a file handle. The file handle
# is passed in as a reference.
sub write_to_file
{
    my $file_ref = shift;
    
    print $file_ref "Hello there";
}

sub main
{
    my $file = "temp.txt";

    # Create a file.
    unless(open FILE, '>'.$file) {
        die "\nCannot create '$file'\n";
    }
    
    # Pass a reference to the file handle
    # to a subroutine.
    write_to_file(*FILE);
    
    close FILE;
}

main();




After running this program, the file "temp.txt" now contains the text "Hello there".

Reference to Subroutines



You can even create references to subroutines. This allows you, for example, to select the subroutine that you want to use based on the value of a variable. One good use of this is in CGI programming, where you can call a particular subroutine based on a URL parameter.

Let's take a look at an example of a program that does this.

#!C:Perlbinperl.exe
# The above line enables Apache to find Perl.

# All variables must be declared.
use strict;

# Warn about uninitialized values.
use warnings;

# Use CGI.pm to get url parameters.
use CGI;

# prints 'hello'
sub hello {
    print "Hello\n";
}

# prints 'Goodbye'
sub goodbye {
    print "Goodbye\n";
}

# Entry point -- called later.
sub main {

    # Print the standard HTML MIME header.
    print 'Content-Type: text/html';
    print "\n\n";
    
    # Get the 'mode' URL parameter
    # If it's not defined, set it to
    # an empty string.
    my $mode = CGI::param('mode') || '';
    
    # Define a hash with strings as the keys
    # and references to subroutines as the values.
    my %routines = (
        'enter' => \&hello,
        'exit' => \&goodbye,
    );
    
    # Try to get a subroutine for the given mode.
    my $routine = $routines{$mode};
    
    # If we didn't find a subroutine corresponding
    # to this mode parameter, quit.
    unless(defined($routine)) {
        print "\nUnknown mode\n";
        die;
    }
    
    # Call the subroutine via its reference.
    $routine->();
}

# Start everything.
main();




If we access this script via a web server using the URL 'http://localhost/test.pl?&mode=enter', the browser outputs "Hello".

What Kind of Perl Reference Is This?



You can use the ref() keyword to find out what kind of thing a reference refers to.

use strict;
use warnings;

sub test {
    print "hello\n";
}

sub main {

    my $text = 'a string';
    
    my $ref1 = \&test;
    my $ref2 = $text;
    my $ref3 = ['an', 'array'];
    my $ref4 = { 'a' => 'hash' };
    my $ref5 = *STDIN;
    
    print ref($ref1), "\n";
    print ref($ref2), "\n";
    print ref($ref3), "\n";
    print ref($ref4), "\n";
    print ref($ref5), "\n";
}

main();




CODE
SCALAR
ARRAY
HASH
GLOB