Programming Perl, Second Edition

Previous Chapter 4 Next
 

4.4 Symbolic References

What happens if you try to dereference a value that is not a hard reference? The value is then treated as a symbolic reference. That is, the reference (which still has a scalar value) is interpreted as a string. That string is taken to be the name of a variable, rather than a direct link to a (possibly anonymous) thingy.

Here is how it works:

$name = "bam";
$$name = 1;                # Sets $bam
${$name} = 2;              # Sets $bam
${$name x 2} = 3;          # Sets $bambam
$name->[0] = 4;            # Sets $bam[0]
@$name = ();               # Clears @bam
&$name();                  # Calls &bam() (as in prior versions of Perl)
$pkg = "THAT";             #  (Don't use "package" or "pack"!)
${"${pkg}::$name"} = 5;    # Sets $THAT::bam without eval

This is very powerful, and slightly dangerous, in that it's possible to intend (with the utmost sincerity) to use a hard reference, and accidentally use a symbolic reference instead. To protect against that, you can say:

use strict 'refs';

and then only hard references will be allowed for the rest of the enclosing block. An inner block may countermand that decree with:

no strict 'refs';

It is important to note the difference between the following two lines of code:

${identifier};    # same as $identifier
${"identifier"};  # also $identifier, but treated as symbolic reference

Because the second form is treated as a symbolic reference, it will generate an error under use strict 'refs'.

Only package variables are visible to symbolic references. Lexical variables (declared with my) aren't in a package symbol table, and thus are invisible to this mechanism. For example:

local $value  = "10";
{
    my $value = "20";
    print ${"value"};
}

This will print "10", not "20". Remember that local affects package variables, which are all global to the package.


Previous Home Next
Using Hard References Book Index Braces, Brackets, and Quoting