Programming Perl, Second Edition

Previous Chapter 4 Next
 

4.5 Braces, Brackets, and Quoting

In the previous section we pointed out that ${identifier} is not treated as a symbolic reference. Now you might wonder how this interacts with reserved words. The short answer is, it doesn't. Despite the fact that push is a reserved word, these two statements:

$push = "pop on ";
print "${push}over";

print out "pop on over". The reason is that, historically, this use of braces is how UNIX shells have delimited a variable name from subsequent alphanumeric text that would otherwise be interpreted as part of the variable name. It's how many people expect variable interpolation to work, so we made it work the same way in Perl. But with Perl, the notion extends further and applies to any braces used in generating references, whether or not they're inside quotes. This means that:

print ${push} . 'over';

or even:

print ${ push } . 'over';

will also print "pop on over", even though the braces are outside of double quotes. The same rule applies to any identifier that is used for subscripting a hash. So, instead of writing:

$hash{ "aaa" }{ "bbb" }{ "ccc" }

you can just write:

$hash{ aaa }{ bbb }{ ccc }

and not worry about whether the subscripts are reserved words. In the rare event that you do wish to do something like:

$hash{ shift }

you can force interpretation as a reserved word by adding anything that makes it more than a mere identifier:

$hash{ shift() }
$hash{ +shift }
$hash{ shift @_ }

The -w switch will warn you if it interprets a reserved word as a string, since you may have meant the reserved word. (That's why we recommend you use ${pkg} instead of ${package} or ${pack}, since you'll avoid some warnings that way.)

Hard References Don't Work as Hash Keys

Consistent with the foregoing, hash keys are stored internally as strings.[7] If you try to store a hard reference as a key in a hash, the key value will be converted into a string:

[7] They're also stored externally as strings, such as when you put them into a DBM file. In fact, DBM files require that their keys (and values) be strings.

$x{ \$a } = $a;
($key, $value) = each %x;
print $$key;   # WRONG

We mentioned earlier that you can't convert a string back to a hard reference. So if you try to dereference $key, which contains a mere string, it won't do a hard dereference, but rather a symbolic dereference, and since you probably don't have a variable named SCALAR(0x1fc0e), you won't accomplish what you're attempting. You might want to do something more like:

$r = \@a;
$x{ $r } = $r;

And then at least you can use the hash value, which will be a hard reference, instead of the key, which won't.

Although you can't store a hard reference as a key, if you use a hard reference in a string context, it is guaranteed to produce a unique string, since the address of the reference is included as part of the resulting string. So you can in fact use a hard reference as a unique hash key. You just can't dereference it later.


Previous Home Next
Symbolic References Book Index A Brief Tutorial: Manipulating Lists of Lists