Perl References

A reference is simply a point to something (a pointer), such as a variable, array, hash or even a subroutine, its an address to a value. References are useful in creating complex data structures. There are two types of references in Perl

hard

Hard references keep track of reference counts, when the reference count becomes zero, Perl automatically frees the item referred to, if the item is an object them the memory is freed
Hard references are easy to use as long as you use scalars, you have to explicity de-reference the variable and tell it how you want it to behave if you do not use scalars.

symbolic
A symbolic reference contains the name of a variable, it is the same principle as a symbolic link in the Unix environment

To use the value of $pointer as the pointer to an array, you reference the items in the array as @$pointer, this notation roughly translates to "take the address in $pointer and then use it as an array". Similarly for hashes, you would use %$pointer as the reference to the first element in the hash.

Using the Backslash Operator

Using the backslash operator means pass the address of an operator

backslash operator example $variable1 = 22;
$variable2 = "A String";

$pointer1 = \$variable1;
$pointer2 = \$variable2;

print "Adress of variable1: $pointer1\n";
print "Adress of variable2: $pointer2\n";

print "Value of variable1 using pointer1: $$pointer1\n";
print "Value of variable2 using pointer2: $$pointer2\n";

References and Arrays

Remember that arrays and hashes are always one-dimensional, you can use the backslah operator just as you would for a scalar variable.

Array example @array = qw( 1 2 3 4 5);

$pointer = \@array;

print "Adress of variable1: $pointer\n";

$i = 0;
foreach (@$pointer) {                    # get the addresses of the elements
   print "[$i] = $$pointer[$i++]\n";
}

print "Value of array using pointer: $$pointer[0] \n";

Using the => operator

%weekday = (
   '01' => 'Mon',
   '02' => 'Tue',
   '03' => 'Wed',
   '04' => 'Thu',
   '05' => 'Fri',
   '06' => 'Sat',
   '07' => 'Sun'
);

$pointer = \%weekday;
$i = '05';

printf "The correct way\n";
printf "==============================================\n";
printf '$$pointer{$i} ' . "is $$pointer{$i} \n";
printf '${$pointer}{$i} ' . "is ${$pointer}{$i} \n";
printf '$pointer->{$i} ' . "is $pointer->{$i} \n\n";

printf "The wrong way\n";
printf "==============================================\n";
printf '${$pointer{$i}} ' . "is ${$pointer{$i}} \n";
printf '${$pointer->{$i}} ' . "is ${$pointer->{$i}} \n";

Multidimensional Arrays

You use square brackets to create a reference to a complex anonymous array.

Multidimensional arrays $line = ['solid', 'black', ['1', '2', '3'] , ['4', '5', '6']];

print "\$line->[0] = $line->[0] \n";
print "\$line->[1] = $line->[1] \n";
print "\$line->[2][0] = $line->[2][0] \n";
print "\$line->[2][1] = $line->[2][1] \n";
print "\$line->[3][0] = $line->[3][0] \n";
print "\$line->[3][1] = $line->[3][1] \n";

Complex example %cube = (
'0', ['0','0','0'],
'1', ['0','0','1'],
'2', ['0','1','0'],
'3', ['0','1','1'],
'4', ['1','0','0']
);

$pointer = \%cube;

foreach $i (sort keys %$pointer) {
   $list = $$pointer{$i};
   $x = $list->[0];
   $y = $list->[1];
   $z = $list->[2];
   ## ($x, $y, $z) = @$list;                   ## you could also use this
   printf "Pointer $i = $x, $y, $z \n";
}

References to Subroutines

You can also reference subroutines as well

Subroutine example sub print_coor {
   my ($x, $y, $z) = @_;
   print "$x $y $z \n";
}

$pointer = \&print_coor;
&{$pointer}(4,5,6);
&$pointer(7,8,9);

The *variable Operator

The asterisk is known as a typeglob, you can use a typeglob in the same way you use a reference because the de-reference syntax always indicates the kind of reference you want. ${*pvalle} and ${\pvalle} both indicate the same scalar variable, *pvalle refers to the entry in the internal _main assiocative array of all symbol names for the _main package, it really translates $_main{'pvalle'} if you are in the _main package context, if you are in another package then it becomes _packageName{}.