Normally, a construct such as $$var indicates that $var is a reference variable, and the programmer expects this expression to return the value that was pointed to by $var when the references were taken.
What if $var is not a reference variable at all? Instead of complaining loudly, Perl checks to see whether $var contains a string. If so, it uses that string as a regular variable name and messes around with this variable! Consider the following:
$x = 10; $var = "x"; $$var = 30; # Modifies $x to 30 , because $var is a symbolic # reference !
When evaluating $$var , Perl first checks to see whether $var is a reference, which it is not; it's a string. Perl then decides to give the expression one more chance: it treats $var 's contents as a variable identifier ( $x ). The example hence ends up modifying $x to 30.
It is important to note that symbolic references work only for global variables, not for those marked private using my .
Symbolic references work equally well for arrays and hashes also:
$var = "x"; @$var = (1, 2, 3); # Sets @x to the enumerated list on the right
Note that the symbol used before
$var
dictates the type of variable to access:
$$var
is equivalent to
$x
, and
@
$var
is equivalent to saying
@
x
.
This facility is immensely useful, and, for those who have done this kind of thing before with earlier versions of Perl, is much more efficient than using eval . Let us say you want your script to process a command-line option such as " -Ddebug_level=3 " and set the $debug_level variable. This is one way of doing it:
while ($arg = shift @ARGV){ if ($arg =~ /-D(\w+)=(\w+)/) { $var_name = $1; $value = $2; $$var_name = $value; # Or more compactly, $$1 = $2; } }
On the other hand, Perl's eagerness to try its damnedest to get an expression to work sometimes doesn't help. In the preceding examples, if you expected the program logic to have a real reference instead of a string, then you would have wanted Perl to point it out instead of making assumptions about your usage. Fortunately, there's a way to switch this eagerness off. Perl has a number of compile-time directives, or pragmas. The strict pragma tells Perl to do strict error checking. You can even enumerate specific aspects to be strict about, one of which is `refs':
use strict 'refs'; # Tell Perl not to allow symbolic references $var = "x"; $$var = 30;
This results in a run-time error whenever you try to use a symbolic reference:
Can't use string ("x") as a SCALAR ref while "strict refs" in use at try.pl line 3
The strict directive remains in effect until the end of the block. It can be turned off by saying no strict or, more specifically, no strict 'refs' .
Copyright © 2001 O'Reilly & Associates. All rights reserved.