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 

This chapter describes:

  • What are symbolic (soft) references and how to use them.
  • How to create hard references.
  • How to use hard references.

Symbolic References

Symbolic references are scalar objects containing strings representing identifiers of variables and functions. Symbolic references are also called soft references. There are several ways to use symbolic references.

1. Directly placing a scalar variable that contains the referencing string in the place where the identifier should be. The following program shows you some examples:

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

Please note that references take higher precedence that subscriptions: [], lookups: {}, and function calls: (). For example, $$name[0] will be evaluated $$name fist, not $name[0] first.

2. Placing an expression that returns the referencing string in curly brackets {} to replace the identifier. Curly brackets are also called lookups. String literals in lookups don't have to be quoted.

The following program shows you some interesting examples. In the first group, I used scalar variables in the lookups. In the second group, I used some string literals and expressions in the lookups. In the third group, I used array elements, hash elements and function returns in the lookups.

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

   ${foo} = 110; print "$foo\n";           
   @{'foo'} = (120); print "$foo[0]\n";    
   ${"foo"}[0] = 130; print "$foo[0]\n";   
   @{'f'.'oo'}[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"; 
   &{'f'.'oo'}(180);                          

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

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

3. If a symbolic 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 referencing string, then followed by an arrow: ->.

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

#- SoftRef3.pl
#- Copyright (c) 1999 by Dr. Herong Yang
#
   $name = 'foo';
   @name = ('foo');
   %name = ('i', 'foo');

   $name->[0] = 30; print "$foo[0]\n";   
   $name->[0,1] = (40,41); print "$foo[0]\n";     # not working
   $name->{'k'} = 60; print "$foo{k}\n";  
   $name->{'k','l'} = (70,71); print "$foo{k}\n"; # not working
   $name->(80);                           

   'foo'->[0] = 130; print "$foo[0]\n";   
   ('bla','foo')->{'k'} = 160; print "$foo{k}\n";  
   ('f'.'oo')->(180);                           

   $name[0]->[0] = 230; print "$foo[0]\n";
   $name{'i'}->{'k'} = 260; print "$foo{k}\n";
   &name->(280);

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

4. Of course, symbolic references can be nested. Here is a program to prove that:

#- SoftRef4.pl
#- Copyright (c) 1999 by Dr. Herong Yang
#
   $a = 'b';
   $b = 'c';
   $c = 'd';
   $d = 'f';
   $f = 'Hi there!';
   print "$$$$$a\n";
   print "${${${${$a}}}}\n";
   $f = 'a';
   print "$$$$$$$$$$$$$a\n";
   print "$$$$$${$$$$$$$a}\n";
   print 'x'->()->()->()->()->()->()->(), "\n";
sub x {return 'y';}
sub y {return 'z';}
sub z {return 'x';}

(Continued on next part...)

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