9 January 2011

"Petrified" references in Perl -- a third type of references

In Perl, one can use soft / symbolic references to variables by creating a variable that contains the name of the referenced variable:

$ref = "myvar";
$$ref = 0; # Sets $myvar to 0

Soft/symbolic references are unsafe, as explained here.

The other way to create a reference is to initialize the reference as a pointer. This is safer as it is explicit:

$ref = \$myvar;
$$ref = 0; # Sets $myvar to 0

$hashref = \%myhash;
$hashref->{'key'} = 0; # This is the same as ${$hashref}{'key'}
$myhash{'key'} = 0; # Has the same effect as the line above

These are called hard references, and Perl's OO system is largely based on them.

However, there is a third case: when two variables point to the same value without either being a reference. (I haven't found an explicit documentation of this, so I named this case "petrified" references.) This can be achieved this way:

*myvar1 = *myvar2;
$myvar1 = 0;
$myvar2 = 0; # Has the same effect as the line above

One can even make a variable point to where a hard reference points to. For example, %myhash2 will point to the anonymous hash referenced by $hashref:

$hashref = {'key' => 0};
*myhash2 = $hashref;
$myhash2{'key'} = 1; # Note that myhash2 is a hash, not a hashref!
$hashref->{'key'} = 1; # Has the same effect as the line above

This is very useful if, for backwards compatibility, one needs to refer to the same value using multiple names, or one needs to cross namespaces.

For some guidance on the * notation, please see section 7 in http://perldoc.perl.org/perlref.html#Making-References.