Perl references: create, dereference and debug with confidence

Learning Perl’s references is a rite-of-passage for Perl programmers. Until you “get” references, large parts of the language will remain alien to you. References have their own special syntax and rules, which can make them seem strange and hard to understand. The good news is that the core features of references are easy to learn and use. This article describes the main ways to use references and some handy tools to get you out of trouble if you run into it. So even if you’re not completely comfortable with references, you’ll be able to write code that works.

What are references?

A reference is a scalar variable whose value is a pointer to another Perl variable. If you were to print out a reference, you would see something like this:

SCALAR(0x509ea0)

The value looks like a memory address, bu it’s actually an internal key for Perl, which points to another variable. A reference can refer to any of Perl’s variable types: scalars, arrays, hashes, filehandles, subroutines and globs. References are useful because they:

save memory - why create two copies of the same variable when you only need one?

enable subroutines to return values that are not in a scalar or list format. (the reference is a scalar pointer to values that can be in any kind of format).

Accessing the value that a reference points to is called “dereferencing”. When you dereference a reference, instead of returning the value of it’s pointer, Perl will fetch the actual variable that the reference is pointing to. The need to dereference a reference variable in order to use it’s underlying value is the main disadvantage of references; direct variable access will always be faster.

Declaring and accessing references

We’re going to focus on array and hash references as those are the most commonly encountered reference types. Working them is easy. For arrays, use square brackets instead of parentheses to declare, and the arrow operator (“->”) to dereference:

$customer is a hash ref with 5 keys. Two of the keys (“name” and “dob”) have the usual scalar values. The other key values though are nested references: “phones” is a nested hashref, and “last_3_purchase_values” and “addresses” are arrayrefs. So how would you access any of the values in $customer data structure? Check this out:

To dereference a value in $customer, we start by using the arrow operator. From there, we add the required key or index to access the next level of data. The main challenge when working with references is to understand the datatype you are dereferencing: if it is an array, you’ll need to use the array accessor syntax “[#]“, whereas if it’s a hash, you need to pass the key in curly braces “{key_value}“.

Working with arrayrefs

Sometimes you’ll need to loop through an arrayref. The syntax for this is the same as an ordinary array, except that you need to dereference the entire array, rather than a single element of it. This is done by enclosing the arrayref in with a dereferencing array block: “@{ $array_ref }“. Let look at some examples using $customer

Here we have pushed a new address on to the “addresses” arrayref. We used a dereferencing array block to dereference “addresses” so that we could perform a push on it.

Working with hashrefs

Dereferencing blocks can be used for hash operations too. Probably the most common operation is looping through the keys of the hash, using the “keys” function. In this case, you’ll need to use a dereferencing hash block “%{ $hash_ref }“. Let’s look at an example using $customer:

Troubleshooting References

References can be harder to debug than normal variables as you need to dereference the reference in order to see what variable it is pointing to. Imagine you wanted to print out the contents of $customer. This doesn’t work:

print $customer; # HASH(0x2683b30)

Fortunately you can use Data::Dumper’s “Dumper” function to dereference and pretty-print a reference for you:

All of these subs are trying to do the same thing - declare an array, loop through it and then return it. Example 1 will return a list of the the array’s elements. This is inefficient as the list comprises of scalar copies of the original array’s elements, which means: Perl makes the copies, returns them and then throws away the original array when it goes out of scope.

Example 2’s main drawback is that by starting with a reference, Perl has to dereference the array in order to loop though it, which is a waste of processing. Example 3 has none of these disadvantages, as it begins with an array, loops through it and then returns a reference to the array. This is a popular Perl programming pattern.

Conclusion

If references were a mystery to you before, hopefully this article helps to kickstart you into using them with confidence. Are you thirsty for more references? There’s a lot more to them than described here. Check out Perl’s official documentation, perldoc which has a tutorial and more detailed guide. Intermediate Perl is fantastic book that has over 100 pages on references (affiliate link).

Site Map

Contact Us

License

Legal

Perl.com and the authors make no representations with respect to the accuracy or completeness of the contents of all work on this website and specifically disclaim all warranties, including without limitation warranties of fitness for a particular purpose. The information published on this website may not be suitable for every situation. All work on this website is provided with the understanding that Perl.com and the authors are not engaged in rendering professional services. Neither Perl.com nor the authors shall be liable for damages arising herefrom.