More than One Reference to Data
What if That Was the Name?
Reference Counting and Nested Data Structures
When Reference Counting Goes Bad
Creating an Anonymous Array Directly
Creating an Anonymous Hash
Autovivification
Autovivification and Hashes
Exercises
References can be copied and passed around like any other scalar. At any given time, Perl knows the number of references to a particular data item. Perl can also create references to anonymous data structures (structures that do not have explicit names) and create references automatically as needed to fulfill certain kinds of operations. Let's look at copying references and how it affects scoping and memory usage.
Chapter 3 explored how to take a reference to an array @skipper and place it into a new scalar variable:
my @skipper = qw(blue_shirt hat jacket preserver sunscreen); my $reference_to_skipper = \@skipper;
You can then copy the reference or take additional references, and they'd all refer to the same thing and be interchangeable:
my $second_reference_to_skipper = $reference_to_skipper; my $third_reference_to_skipper = \@skipper;
At this point, you have four different ways to access the data contained in @skipper:
@skipper @$reference_to_skipper @$second_reference_to_skipper @$third_reference_to_skipper
Perl tracks how many ways the data can be accessed through a mechanism called reference counting. The original name counts as one, and each additional reference that was taken (including copies of references) also counts as one. The total number of references to the array of provisions is now four.
You can add and remove references as you wish, and as long as the reference count doesn't hit zero, the array is maintained in memory and is still accessible via any of the other access paths. For example, you might have a temporary reference:
check_provisions_list(\@skipper)
When this subroutine begins executing, a fifth reference to the data is created and copied into @_ for the subroutine. The subroutine is free to create additional copies of that reference, which Perl notes as needed. Typically, when the subroutine returns, all such references are discarded automatically, and you're back to four references again.
You can kill off each reference by using the variable for something other than a reference to the value of @skipper. For example, you can assign undef to the variable:
$reference_to_skipper = undef;
Or, maybe just let the variable go out of scope:
my @skipper = ...; { ... my $ref = \@skipper; ... ... } # $ref goes out of scope at this point
In particular, a reference held in a subroutine's private (lexical) variable goes away at the end of the subroutine.
Whether the value is changed or the variable itself goes away, Perl notes it as an appropriate reduction in the number of references to the data.
Perl recycles the memory for the array only when all references (including the name of the array) go away. In this case, memory is reclaimed when @skipper goes out of scope, as well as all other references that had been taken to @skipper are removed or modified to be another value. Such memory is available to Perl for other data later in this program invocation but generally will not be returned to the operating system for use by other processes.
Copyright © 2003 O'Reilly & Associates. All rights reserved.