Herong's Tutorial Notes on Perl - Part A
Dr. Herong Yang, Version 4.09

perlref - Perl References and Nested Data Structures

Part:   1  2  3  

(Continued from previous part...)

The following program shows you some interesting examples. In the first group, I used scalar variables that contain hard references in the lookups. In the second group, I used hard references directly in the lookups. In the third group, I used an array to store the hard references.

#- HardRef2.pl
#- Copyright (c) 1999 by Dr. Herong Yang
#
   $foo = 0;
   @foo = (0);
   %foo = (k,0);
   $refs = \$foo;
   $refa = \@foo;
   $refh = \%foo;
   $reff = \&foo;
   @refl = (\$foo, \@foo, $refh, $reff);
   
   ${$refs} = 10; print "$foo\n";           # the scalar of $foo
   @{$refa} = (20); print "$foo[0]\n";      # entire array of @foo
   ${$refa}[0] = 30; print "$foo[0]\n";     # an element of @foo
   @{$refa}[0] = (40); print "$foo[0]\n";   # a slice of @foo
   %{$refh} = ('k',50); print "$foo{k}\n";  # entire hash of %foo
   ${$refh}{'k'} = 60; print "$foo{k}\n";   # an element of %foo
   @{$refh}{'k'} = (70); print "$foo{k}\n"; # a slice of %foo
   &{$reff}(80);                            # calling &foo

   ${\$foo} = 110; print "$foo\n";           
   @{\@foo} = (120); print "$foo[0]\n";    
   ${\@foo}[0] = 130; print "$foo[0]\n";   
   @{\@foo}[0] = (140); print "$foo[0]\n";   
   %{\%foo} = ('k',150); print "$foo{k}\n";
   ${\%foo}{'k'} = 160; print "$foo{k}\n"; 
   @{\%foo}{'k'} = (170); print "$foo{k}\n"; 
   &{\&foo}(180);                          

   ${$refl[0]} = 210; print "$foo\n";       
   @{$refl[1]} = (220); print "$foo[0]\n";
   ${$refl[1]}[0] = 230; print "$foo[0]\n";    
   @{$refl[1]}[0] = (240); print "$foo[0]\n";
   %{$refl[2]} = ('k',250); print "$foo{k}\n";
   ${$refl[2]}{'k'} = 260; print "$foo{k}\n";
   @{$refl[2]}{'k'} = (270); print "$foo{k}\n";
   &{$refl[3]}(280);                       

sub foo {print "$_[0]\n";}

3. If a hard reference is used to access a single element of an array, to access a single element of hash, or to call a function, you can remove the name space prefix character $, or &, and replace the identifier with an expression that returns the hard reference, then followed by an arrow: ->.

The following program shows you some examples. Note that you can not use -> to access slices.

#- HardRef3.pl
#- Copyright (c) 1999 by Dr. Herong Yang
#
   $foo = 0;
   @foo = (0);
   %foo = (k,0);
   $refs = \$foo;
   $refa = \@foo;
   $refh = \%foo;
   $reff = \&foo;
   @refl = (\$foo, \@foo, $refh, $reff);
   
   $refa->[0] = 30; print "$foo[0]\n";   
   $refa->[0,1] = (40,41); print "$foo[0]\n";     # not working
   $refh->{'k'} = 60; print "$foo{k}\n";  
   $refh->{'k','l'} = (70,71); print "$foo{k}\n"; # not working
   $reff->(80);                           

   (\@foo)->[0] = 130; print "$foo[0]\n";         # \@foo->[0] is bad
   ('bla',\%foo)->{'k'} = 160; print "$foo{k}\n";  
   $refl[3]->(180);                           

sub foo {print "$_[0]\n";}

4. Of course, hard references can be nested. They can also be mixed with soft (symbolic) references. Here is a program to prove that:

#- HardRef4.pl
#- Copyright (c) 1999 by Dr. Herong Yang
#
   $z = "99.99";
   $y = \$z;
   $x = \$y;
   $a = 'y';
   $b = \$a;
   print "$$$x\n";
   print "$$$a\n";
   print "$$$$b\n";

5. A hard reference can also be used as scalar.

  • It will return an integer representing the memory location of the referenced object, if a number is expected.
  • It will return the object type and memory location in hex of the referenced object, if a string is expected.
  • It will return TRUE, if a boolean value is expected.

Here is a program to help you understand this:

#- HardRef5.pl
#- Copyright (c) 1999 by Dr. Herong Yang
#
   $a = 3;
   $b = 5;
   $x = '1234';
   $y = 'abcd';
   @l = (3,5,7,11);
   print '\$a = ', \$a, "\n";
   print '\$b = ', \$b, "\n";
   print '\$x = ', \$x, "\n";
   print '\$y = ', \$y, "\n";
   print '\@l = ', \@l, "\n";
   print '\$l[0] = ', \$l[0], "\n";
   print '\$l[1] = ', \$l[1], "\n";
   print '\$b - \$a = ', \$b - \$a, "\n";
   print '\$y - \$x = ', \$y - \$x, "\n";
   print '\$l[1] - \$l[0] = ', \$l[1] - \$l[0], "\n";

Output:

\$a = SCALAR(0x1ab2e38)
\$b = SCALAR(0x1ab2e5c)
\$x = SCALAR(0x1ab2e80)
\$y = SCALAR(0x1ab2ea4)
\@l = ARRAY(0x1ab2ed4)
\$l[0] = SCALAR(0x1abf074)
\$l[1] = SCALAR(0x1abf128)
\$b - \$a = 36
\$y - \$x = 36
\$l[1] - \$l[0] = 180

Part:   1  2  3  

Dr. Herong Yang, updated in 2006
Herong's Tutorial Notes on Perl - Part A - perlref - Perl References and Nested Data Structures