Going Deeper

The creation and use of references is probably one of the more complex aspects of Perl (arguably surpassed only by object-oriented programming, which we'll look at tomorrow). In today's lesson I've introduced you to the basics of references and the places where you'll most commonly use them. But as with most Perl topics, there's plenty of other features I haven't covered that relate to references, including symbolic references (a whole other form of reference), and references to subroutines, typeglobs, and filehandles.

For more information on references, check out the perlref man page. If you do more work with nested data structures, the man pages perldsc (data structures cookbook) and perllol (lists of lists) provide further detail and examples.

Shorthand References to Scalars

Need to create a lot of scalar references at once? Here's an easy way to do it:

@listofrefs = ($thing1, $thing2, $thing3, $thing4);

Here you'll end up with a list of references in @listofrefs. It's a shorthand for something doing this:

@listofrefs = ($thing1, $thing2, $thing3, $thing4);

Symbolic References

As I mentioned in passing earlier in this lesson, Perl actually defines two kinds of references: hard references and symbolic references. The references I've used throughout this lesson are hard references that are actual bits of scalar data that can be manipulated like scalars or dereferenced to get to the data they refer to.

Symbolic references are different: a symbolic reference is simply a string. If you try to dereference that string, the string is interpreted to be the name of a variable, and if that variable exists, you get the value of that variable. So, for example:

$foo = 1;         # variable $foo contains 1
$symref = "foo";  # string
$$symref = "I am a variable"; # sets the variable $foo
print "synbolic reference: $symref
";    # results in "foo"
print "Foo: $foo
";  # results in "I am a variable"
print "dereferenced: $$symref
";   # prints $foo, results in "I am a variable"

As you can see, you can use symbolic references as if they were real references, but they're just strings that name variables. The difference is subtle and confusing, particularly if you mix hard and symbolic references. You can accidentally dereference a string when you meant to dereference a scalar, and end up with it being difficult to debug problems. For this reason, Perl provides a strict pragma to restrict the use of references to hard references:

use strict 'refs';

Setting this pragma at the top of your script will prevent you from using symbolic references. You'll also get this effect if you use a regular use strict at the top of your script as well.

References to Typeglobs and Filehandles

Two types of references I didn't mention in the body of this lesson were references to typeglobs, which in turn allow references to filehandles. A typeglob, as I've mentioned in passing previously in this book, is a way of referring to multiple types of variables that share the same name (it holds an actual symbol table entry). Typeglobs are not as commonly used in Perl as they were in the past (they used to be how you passed references to lists into subroutines before there were references), but they do provide a mechanism for creating references to filehandles, which allows you to pass filehandles into and out of subroutines, or to create local filehandles, if you feel the need to do so.

To create a reference to a filehandle, use a typeglob with the name of the filehandle and the backslash operator ():

$fh = *MYFILE;

To create a local filehandle, use the local operator (not my) and a filehandle typeglob:

local *MYFILE;

See the perldata man page (the section on typeglobs and filehandles) for details.

References to Subroutines

Much more useful than references to filehandles are references to subroutines. Given that a subroutine's definition is stored in memory just as an array or hash is, you can create references to subroutines just as you can references to other bits of data. By dereferencing the reference to a subroutine, you call that subroutine.

References to subroutines allow you to change the definition of a subroutine on-the-fly, or to choose between several different subroutines depending on the situation. They also allow advanced features in Perl such as object-oriented programming and closures (anonymous subroutines whose local variables “stick” based on the time and scope in which they were defined, even if they're called in a different scope).

To create a reference to a subroutine, you can use the backslash operator with the name of a predefined subroutine:

$subref = &mysub;

You can also create an anonymous subroutine by simply leaving off the name of the subroutine when you define it:

$subref = sub { reverse @_;} ;

Dereference a subroutine using regular reference syntax or with a block. When you de-reference a subroutine, you call it, so don't forget to include arguments:

@result = &$subref(1..10);

For more details on references to subroutines, and of closures, see the perlref man page.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset