References
| Take a reference | |
| Dereference | |
| Anonymous structures | |
| Ask what it is | |
| Pass big data cheaply |
Take a reference
A reference is a scalar that points at another piece of data. Take one with a backslash: a reference to an array, a hash, or a single scalar is still just one value, so it fits in a scalar variable.
my @langs = qw(perl ruby);
my %user = (name => "Ada");
my $aref = \@langs;
my $href = \%user;
The backslash is what turns a list or a hash into one scalar. Without it, assigning @langs to a scalar would give a count, not the data.
Dereference
To read through a reference, put the sigil in front of it. A scalar reference takes a dollar, an array reference takes an at sign, and a hash reference takes a percent sign.
my @langs = qw(perl ruby);
my %user = (name => "Ada");
my ($aref, $href) = (\@langs, \%user);
print @$aref, "\n"; # perlruby, print adds no separator
print $aref->[0], "\n"; # perl
print $href->{name}, "\n"; # Ada
perl demo.pl
perlruby
perl
Ada
The arrow form works for one element and is the one you will read most often. Braces around the reference are also allowed and help when the expression is not a plain name: @{$aref}.
Anonymous structures
Square brackets build an unnamed array and return its reference; curly braces do the same for a hash. This is how nested data starts, because the reference is a scalar and can sit inside another structure.
my $aref2 = [1, 2, 3];
my $href2 = { name => "Ada", age => 36 };
print $aref2->[2], " ", $href2->{age}, "\n"; # 3 36
perl demo.pl
3 36
The brackets and braces here are not the same as the parentheses of a list. A list in parentheses is still a list; only the bracket forms produce a reference.
Ask what it is
ref tells you what a reference points at, and returns an empty string for a plain value. It is the standard guard before dereferencing something that came from outside your code.
my $aref2 = [1, 2, 3];
my $href2 = { name => "Ada", age => 36 };
print ref $aref2, "\n"; # ARRAY
print ref $href2, "\n"; # HASH
print ref "text", "\n"; # empty line
print "---\n"; # marker, so the empty line is visible
perl demo.pl
ARRAY
HASH
---
Pass big data cheaply
Arguments in @_ are aliases, so passing an array is not as expensive as it looks. But returning a big list copies it, and storing two copies becomes a real cost; a reference moves one pointer instead.
my $aref2 = [1, 2, 3];
sub count_items {
my ($list) = @_;
return scalar @$list;
}
print count_items($aref2), "\n"; # 3
perl demo.pl
3
References also let a subroutine change the caller data on purpose, for example to fill a results hash that the caller owns. Lesson 20 builds the nested shapes that make this technique worth the syntax.
Next: Nested data structures
Article author: Arthur Isaev