- publishing free software manuals
Perl Language Reference Manual
by Larry Wall and others
Paperback (6"x9"), 724 pages
ISBN 9781906966027
RRP £29.95 ($39.95)

Sales of this book support The Perl Foundation! Get a printed copy>>>

15.3 Using References

That's it for creating references. By now you're probably dying to know how to use references to get back to your long-lost data. There are several basic methods.

  1. Anywhere you'd put an identifier (or chain of identifiers) as part of a variable or subroutine name, you can replace the identifier with a simple scalar variable containing a reference of the correct type:
    $bar = $$scalarref;
    push(@$arrayref, $filename);
    $$arrayref[0] = "January";
    $$hashref{"KEY"} = "VALUE";
    &$coderef(1,2,3);
    print $globref "output\n";
    
    It's important to understand that we are specifically not dereferencing $arrayref[0] or $hashref{"KEY"} there. The dereference of the scalar variable happens before it does any key lookups. Anything more complicated than a simple scalar variable must use methods 2 or 3 below. However, a "simple scalar" includes an identifier that itself uses method 1 recursively. Therefore, the following prints "howdy".
    $refrefref = \\\"howdy";
    print $$$$refrefref;
    
  2. Anywhere you'd put an identifier (or chain of identifiers) as part of a variable or subroutine name, you can replace the identifier with a BLOCK returning a reference of the correct type. In other words, the previous examples could be written like this:
    $bar = ${$scalarref};
    push(@{$arrayref}, $filename);
    ${$arrayref}[0] = "January";
    ${$hashref}{"KEY"} = "VALUE";
    &{$coderef}(1,2,3);
    $globref->print("output\n");  # iff IO::Handle is loaded
    
    Admittedly, it's a little silly to use the curlies in this case, but the BLOCK can contain any arbitrary expression, in particular, subscripted expressions:
    &{ $dispatch{$index} }(1,2,3);      # call correct routine
    
    Because of being able to omit the curlies for the simple case of $$x, people often make the mistake of viewing the dereferencing symbols as proper operators, and wonder about their precedence. If they were, though, you could use parentheses instead of braces. That's not the case. Consider the difference below; case 0 is a short-hand version of case 1, not case 2:
    $$hashref{"KEY"}   = "VALUE";       # CASE 0
    ${$hashref}{"KEY"} = "VALUE";       # CASE 1
    ${$hashref{"KEY"}} = "VALUE";       # CASE 2
    ${$hashref->{"KEY"}} = "VALUE";     # CASE 3
    
    Case 2 is also deceptive in that you're accessing a variable called %hashref, not dereferencing through $hashref to the hash it's presumably referencing. That would be case 3.
  3. Subroutine calls and lookups of individual array elements arise often enough that it gets cumbersome to use method 2. As a form of syntactic sugar, the examples for method 2 may be written:
    $arrayref->[0] = "January";   # Array element
    $hashref->{"KEY"} = "VALUE";  # Hash element
    $coderef->(1,2,3);            # Subroutine call
    
    The left side of the arrow can be any expression returning a reference, including a previous dereference. Note that $array[$x] is not the same thing as $array->[$x] here:
    $array[$x]->{"foo"}->[0] = "January";
    
    This is one of the cases we mentioned earlier in which references could spring into existence when in an lvalue context. Before this statement, $array[$x] may have been undefined. If so, it's automatically defined with a hash reference so that we can look up {"foo"} in it. Likewise $array[$x]->{"foo"} will automatically get defined with an array reference so that we can look up [0] in it. This process is called autovivification. One more thing here. The arrow is optional between brackets subscripts, so you can shrink the above down to
    $array[$x]{"foo"}[0] = "January";
    
    Which, in the degenerate case of using only ordinary arrays, gives you multidimensional arrays just like C's:
    $score[$x][$y][$z] += 42;
    
    Well, okay, not entirely like C's arrays, actually. C doesn't know how to grow its arrays on demand. Perl does.
  4. If a reference happens to be a reference to an object, then there are probably methods to access the things referred to, and you should probably stick to those methods unless you're in the class package that defines the object's methods. In other words, be nice, and don't violate the object's encapsulation without a very good reason. Perl does not enforce encapsulation. We are not totalitarians here. We do expect some basic civility though.

Using a string or number as a reference produces a symbolic reference, as explained above. Using a reference as a number produces an integer representing its storage location in memory. The only useful thing to be done with this is to compare two references numerically to see whether they refer to the same location.

if ($ref1 == $ref2) {  # cheap numeric compare of references
    print "refs 1 and 2 refer to the same thing\n";
}

Using a reference as a string produces both its referent's type, including any package blessing as described in 16, as well as the numeric address expressed in hex. The ref() operator returns just the type of thing the reference is pointing to, without the address. See for details and examples of its use.

The bless() operator may be used to associate the object a reference points to with a package functioning as an object class. See 16.

A typeglob may be dereferenced the same way a reference can, because the dereference syntax always indicates the type of reference desired. So ${*foo} and ${\$foo} both indicate the same scalar variable.

Here's a trick for interpolating a subroutine call into a string:

print "My sub returned @{[mysub(1,2,3)]} that time.\n";

The way it works is that when the @{...} is seen in the double-quoted string, it's evaluated as a block. The block creates a reference to an anonymous array containing the results of the call to mysub(1,2,3). So the whole block returns a reference to an array, which is then dereferenced by @{...} and stuck into the double-quoted string. This chicanery is also useful for arbitrary expressions:

print "That yields @{[$n + 5]} widgets\n";

Similarly, an expression that returns a reference to a scalar can be dereferenced via ${...}. Thus, the above expression may be written as:

print "That yields ${\($n + 5)} widgets\n";
ISBN 9781906966027Perl Language Reference ManualSee the print edition