[ Perl tips index]
[ Subscribe to Perl tips ]
Last week we discussed Scalar::Util and covered, amongst other things, how
to weaken references so that circular references no longer cause memory
leaks. This week we're going to talk more about references and their many
uses.
We'll begin with a brief overview of variable references, which are most commonly seen, and next week we'll look at some more exotic species.
We can take a reference to a scalar, hash or array by placing a backslash before its sigil (the punctuation at the start of the variable). Here are some examples:
my $scalar_ref = \$scalar;
my $array_ref = \@array;
my $hash_ref = \%hash;
Note that our references are all contained in scalars. This means that we can use references where ever we would normally require a scalar. We can use references in arrays, or as the values in a hash.
Of course, having a reference isn't very useful if we can't retrieve the underlying data structure. To de-reference a variable, we simply put the required sigil back on the front.
# Add 6 to the value in $scalar_ref.
$$scalar_ref += 6;
# Push 'apple' onto the end of the array in $array_ref.
push @$array_ref, 'apple';
# Retrieve a list of keys from $hash_ref.
my @keys = keys %$hash_ref;
When we're dealing with references to arrays and hashes, we often wish to access an individual element, rather than the entire hash or array itself. Perl gives us a shortcut for these simple operations, using what is commonly referred to as arrow notation.
# Look up an value from an array reference, using its index.
# Note that we use square-brackets for array look-ups.
$array_ref->[0];
# Look up a value from a hash reference, using its key.
# Note that we use curly-braces for hash look-ups.
$hash_ref->{flintstone};
If we always had to create the array or hash before we could get a reference to it, there would be much less point. Fortunately, Perl allows us to create anonymous data structures as well.
We can create array and hash references in one step as follows:
my $array_ref = [ qw/zero one two three four/ ];
my $hash_ref = {
zero => 0,
one => 1,
two => 2,
three => 3,
four => 4,
};
Notice that we use square brackets to create an array reference and curly braces to create a hash reference. This makes it easy to remember; we use the same type of braces as we do to look up values in the respective data structure. As we use square brackets to look up a value in an array, we use square brackets to create an array reference. Likewise we use curly braces to look up a value in a hash and to create a hash reference.
The above structures are called anonymous arrays and hashes. This is because the array (and hash) itself does not have a name and cannot be accessed separately from the reference.
Variable references are primarily used in three kinds of situations:
If we pass more than one list structure (arrays, hashes or both) into
a subroutine Perl helpfully flattens them into one big list and puts
all the values in @_, losing the identity of each structure.
Sometimes this is what we want, but there will be occasions when we
want to pass arrays or hashes that keep their identity. References
allow us to do this in a simple and elegant fashion.
intersection(\@array1, \@array2);
# Find the intersection between two arrays.
sub intersection {
my ($first, $second) = @_;
# We can now de-reference back into original arrays,
# or use the arrow notation to access individual
# elements.
}
Arrays and hashes can only contain scalar values. However, since references are scalar values, we can build multi-dimensional data structures through the use of references.
my %multihash = (
jarich => {
company => "Perl Training Australia",
name => "Jacinta Richardson"
},
pjf => {
company => "Perl Training Australia",
name => "Paul Fenwick"
},
fred => {
company => "XYZ Retail",
name => "Fred Bloggs",
}
);
print $multihash{jarich}->{name};
Notice that to build the multi-dimensional hash in this example, we've used anonymous data structures. It's also possible to build hashes of arrays, arrays of hashes and even hashes of arrays of hashes of arrays.
Sometimes you might need to know what kind of reference you have. Is it a
reference to a hash, array or scalar? Or is it a different kind of
reference that we haven't covered yet? Fortunately, Perl has a function
which will answer this question for us: ref.
my $scalar_ref = \$scalar;
my $array_ref = \@array;
my $hash_ref = \%hash;
print ref($scalar_ref), "\n"; # Prints SCALAR
print ref($array_ref), "\n"; # Prints ARRAY
print ref($hash_ref), "\n"; # Prints HASH
Printing the data structure pointed to by a reference can get difficult quickly, especially since the data structures can get quite complex and are not required to conform to any specific structure. Just as arrays can contain both numeric and string data, an array can also contain references to other arrays as well as other hashes, all mixed in with data.
Fortunately the problem of printing the contents of a reference has been
solved and thus we have Data::Dumper. This allows us to write:
use Data::Dumper;
print Dumper(\%multihash);
to get back:
$VAR1 = {
'fred' => {
'name' => 'Fred Bloggs',
'company' => 'XYZ Retail'
},
'pjf' => {
'name' => 'Paul Fenwick',
'company' => 'Perl Training Australia'
},
'jarich' => {
'name' => 'Jacinta Richardson',
'company' => 'Perl Training Australia'
}
};
Data::Dumper can also be used with objects to see their internal state:
use Data::Dumper;
use LWP::UserAgent;
$ua = LWP::UserAgent->new;
print Dumper $ua;
this prints:
$VAR1 = bless( {
'agent' => 'libwww-perl/5.64',
'protocols_forbidden' => undef,
'proxy' => undef,
'protocols_allowed' => undef,
'use_eval' => 1,
'max_size' => undef,
'from' => undef,
'requests_redirectable' => [
'GET',
'HEAD'
],
'timeout' => 180,
'parse_head' => 1,
'no_proxy' => []
}, 'LWP::UserAgent' );
Next week we'll talk about some other kinds of references.
[ Perl tips index ]
[ Subscribe to Perl tips ]
| Location | Course | Course Date | Duration | Early Bird Date |
|---|---|---|---|---|
| Melbourne | Programming Perl | Tue 2 Sep 2008 | 4 days | Mon 4 Aug 2008 |
| Sydney | Programming Perl | Tue 7 Oct 2008 | 4 days | Mon 8 Sep 2008 |
| Canberra | Programming Perl | Mon 24 Nov 2008 | 4 days | Mon 27 Oct 2008 |
For future dates, please see our training calendar.
This Perl tip and associated text is copyright Perl Training Australia. You may freely distribute this text so long as it is distributed in full with this Copyright noticed attached.
If you have any questions please don't hesitate to contact us:
| Email: | contact@perltraining.com.au |
| Phone: | 03 9354 6001 (Australia) |
| International: | +61 3 9354 6001 |
Copyright 2001-2008 Perl Training Australia. Contact us at contact@perltraining.com.au