Programming Perl, Second Edition

Previous Chapter 4
References and Nested Data Structures
Next
 

4.2 Creating Hard References

There are several ways to compose references, most of which we will describe before explaining how to use (dereference) the resulting references.

The Backslash Operator

You can create a reference to any named variable or subroutine by using the unary backslash operator. (You may also use it on an anonymous scalar value.) This works much like the & (address-of) operator in C.

Here are some examples:

$scalarref = \$foo;
$constref  = \186_282.42;
$arrayref  = \@ARGV;
$hashref   = \%ENV;
$coderef   = \&handler;
$globref   = \*STDOUT;

The Anonymous Array Composer

You can create a reference to an anonymous array by using brackets:

$arrayref = [1, 2, ['a', 'b', 'c']];

Here we've composed a reference to an anonymous array of three elements whose final element is a reference to another anonymous array of three elements.

These square brackets work like this only where the Perl parser is expecting a term in an expression, and should not be confused with the brackets that are functioning as operators when used to subscript an array (though there is an obvious mnemonic association with arrays). Square brackets inside a quoted string do not result in the interpolation of a reference to an anonymous array. Rather, such brackets become literal elements in the string. (However, if you're interpolating something into the string, and the expression defining the interpolation contains brackets, they have their normal meaning within the expression, since they are, after all, in an expression.)

Note that taking a reference to an enumerated list is not the same as using brackets--instead it's treated as a shorthand for creating a list of references:

@list = (\$a, \$b, \$c);  
@list = \($a, $b, $c);      # same thing!

The Anonymous Hash Composer

You can create a reference to an anonymous hash by using braces:

$hashref = {
    'Adam'  => 'Eve',
    'Clyde' => 'Bonnie',
};

The values above are literal strings; variables and expressions would work as well. Also, for the values (but not the keys) of the hash, you can freely mix anonymous hash and array composers to produce as complicated a structure as you want.

These braces work like this only where the Perl parser is expecting a term in an expression, and should not be confused with the braces that are functioning as operators when used to subscript a hash (though there is an obvious mnemonic association with hashes). Braces inside a quoted string do not result in the interpolation of a reference to an anonymous hash. Rather, such braces become literal elements in the string. (However, the same caveat about interpolating expressions applies to braces as it does to brackets.)

Since braces are also used for several other things including BLOCKs, you may occasionally have to disambiguate braces at the beginning of a statement by putting a + or a return in front so that Perl realizes the opening brace isn't starting a BLOCK. For example, if you wanted a function to make a new hash and return a reference to it, you have these options:

sub hashem {        { @_ } }   # silently WRONG
sub hashem {       +{ @_ } }   # ok
sub hashem { return { @_ } }   # ok

The Anonymous Subroutine Composer

You can create a reference to an anonymous subroutine by using sub without a subroutine name:

$coderef = sub { print "Boink!\n" };

Note the presence of the semicolon, which is required here to terminate the expression. (It wouldn't be required after the declaration of a named subroutine.) A nameless sub {} is not so much a declaration as it is an operator--like do {} or eval {}--except that the code inside isn't executed immediately. Instead, it just generates a reference to the code and returns that. However, no matter how many times you execute the line shown above, $coderef will still refer to the same anonymous subroutine.[4]

[4] But see later about closures. Even though there's only one anonymous subroutine, there may be several copies of the lexical variables in use by the subroutine, depending on when the subroutine reference was generated.

Object Constructors

Subroutines can also return references. That may sound trite, but sometimes you are supposed to use a subroutine to create a reference rather than creating the reference yourself. In particular, special subroutines called constructors return references to objects. An object is simply a special kind of thingy that happens to know which class it's associated with. Constructors know how to create that association. They do so by taking an ordinary thingy and turning it into an object (which remains a thingy even while it's also being an object). The operator that a constructor uses to do this is called bless, so we can speak of an object as a blessed thingy. Constructors are customarily named new(), but don't have to be. They're usually called in one of two ways:

$objref = new Doggie Tail => 'short', Ears => 'long';
   # same as
$objref = Doggie->new(Tail => 'short', Ears => 'long');

See Chapter 5, Packages, Modules, and Object Classes, for a discussion of Perl objects.

Filehandle Referencers

References to filehandles can be created by taking a reference to a typeglob. This is currently the best way to pass named filehandles into or out of subroutines, or to store them in larger data structures.

splutter(\*STDOUT);
sub splutter {
    my $fh = shift;
    print $fh "her um well a hmmm\n";
}
$rec = get_rec(\*STDIN);
sub get_rec {
    my $fh = shift;
    return scalar <$fh>;
}

However, if you don't need to refer to existing named filehandles, you should consider using one of the newer, object-oriented library modules that provide filehandle objects via a constructor (see the previous section). In either case, you won't use filehandle names directly, but rather you'll use scalars (as above) to hold a reference to something that will (one way or another) be interpreted as a filehandle. As we admitted earlier, there is some implicit dereferencing magic going on here.

Implicit Creation of References

A final method for creating references is not really a method at all. References of an appropriate type simply spring into existence if you dereference them in a context that assumes they exist. This is extremely useful, and is also What You Expect. This topic is covered in the next section.


Previous Home Next
What Is a Reference? Book Index Using Hard References

HTML: The Definitive Guide CGI Programming JavaScript: The Definitive Guide Programming Perl WebMaster in a Nutshell
Hosted by uCoz