Siaris

Understanding References, Part 1
05 Apr 01 - http://www.siaris.net/index.cgi/Programming/LanguageBits/Perl/20010405.rdoc

As you probably already know, Perl has three basic variable types: scalar variables, array variables, and hash variables. A scalar variable holds a scalar value (one thing, either a number, a string, or a reference). An array holds a list of scalar values, and a hash holds a set of key/value pairs where each value is a scalar value.

But, what if we want to have a two dimensional array? We cannot simply do this:

    my @foo  = (1,2,3);
    my @bar  = (4,5,6);
    my @twod = (@foo, @bar);

Well, we can do that, but it does not give us a two dimensional array — it gives us a single array hold (1,2,3,4,5,6). The trick is to use references. We saw above that a reference is a scalar value, but we have not yet said what a reference is. Consider the following simple assignment:

    my $foo = 30;

A simple way to think about this is that the number 30 is stored in a slot in memory. All such memory slots have an address (a slot number), and Perl internally associates the variable $foo with the slot address where it stored the number 30. The only way we can access that number again is through the variable $foo (which knows which slot it is in). So, $foo has a slot number (address) and when we access $foo we access that slot. What happens in the following?

    my $foo = 30;
    my $bar = $foo;

The first assignment is the same as the above, but what happens with the assignment to $bar? Well, Perl first gives $bar its own memory slot, and then assigns the number stored in $foo’s slot (copies it) into $bar’s slot. Now the number 30 is stored in two different slots. If we then do: $foo = 42; What happens? All that happens is that we assign a new number into $foo’s slot — we did not touch $bar at all and it remains unchanged (still holding 30).

A reference, then, is simply the slot number (address) of another variable (instead of its contents). We can take a reference using the backslash operator (future articles will discuss other ways of creating a reference):

    my $foo = 30;
    my $bar = \$foo;

Now $bar still has its own slot, but instead of assigning the contents of $foo’s slot into it, we assign $foo’s slot number itself. If we then print out $bar we see that it does not hold 30:

    my $foo = 30;
    my $bar = \$foo;
    print "$bar\n";   #prints: SCALAR(0x80ee87c)

When we print a reference it tells us the type of reference (SCALAR in this case) and the memory address (0x80ee87c in this case, but if you try it you will probably get a different number). The address is just a hexadecimal number, but that doesn’t matter for the purposes of our discussion. Now, how can use this reference? We have to dereference it:

    my $foo = 30;
    my $bar = \$foo;
    print "$$bar\n";         # prints: 30
    $$bar = 42;
    print "$foo : $$bar\n";  # prints: 42 : 42

Notice that we used $$bar (two $ signs) to dereference the variable. When we print out the dereferenced value we get the contents of the memory slot it was pointing to — and similarly, when we assigned into the dereferenced variable we assigned into the slot it was pointing to, so the contents of $foo’s slot were actually changed. It may not look like we have much at this point, merely adding an extra step to get to the contents of a variable — but I assure you, this is a foundation for a great deal of usefulness as we will see in the next few articles.

*****