×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Jobs

References in Perl

How do I pass a reference to a subroutine? by hmerrill
Posted: 26 Jan 01

First, I want to make you aware of the documentation on "references" that comes with Perl - by doing "perldoc perl"(at least in *nix), two of the lines I get that refer to references specifically are these:

     perlreftut          Perl references short introduction
     perlref             Perl references, the rest of the story

Then, by doing "perldoc perlreftut", I can view "Perl references short introduction".

Below is an example that describes how you can pass references to a subroutine, and use those references in the subroutine to change the values of the variables that those references point to:

-------------------------------------------------------------------

#!/usr/bin/perl -w

use strict;

sub something {
   my $ref_scalar_a = shift;
   my $ref_array_a  = shift;
   my $ref_hash_a   = shift;

   ${$ref_scalar_a}  = "z";   ### Must dereference the reference
   $ref_array_a->[0] = "zzz"; ### Changes the value of the 1st element("a")
                                        ###   to "zzz".
   $ref_hash_a->{'a'} = "xyz"; ### Changes the value of the 1st element
                                          ###   keyed by "a" to "xyz".
} ### end sub something

########## Main ###########
my $a           = "a";
my @array_a = ("a", "b", "c");
my %hash_a  = ("a" => "aaa",
                       "b" => "bbb",
                       "c" => "ccc");
print "\n";
print "before: scalar \$a = <$a>\n";
print "before: array \@array_a = " . join(', ', @array_a) . "\n";
foreach my $key (keys %hash_a) {
   print "before: hash key=<$key>, value=<$hash_a{$key}>\n";
}
### Call something subroutine ###
something(\$a, \@array_a, \%hash_a);

print "\n";
print "after : scalar \$a = <$a>\n";
print "after : array \@array_a = " . join(', ', @array_a) . "\n";
foreach my $key (keys %hash_a) {
   print "after : hash key=<$key>, value=<$hash_a{$key}>\n";
}

-------------------------------------
Here's the output:

before: scalar $a = <a>
before: array @array_a = a, b, c
before: hash key=<a>, value=<aaa>
before: hash key=<b>, value=<bbb>
before: hash key=<c>, value=<ccc>

after : scalar $a = <z>
after : array @array_a = zzz, b, c
after : hash key=<a>, value=<xyz>
after : hash key=<b>, value=<bbb>
after : hash key=<c>, value=<ccc>
-------------------------------------

The thing to remember is that when you pass a reference to a subroutine, that's exactly what the subroutine receives - a reference.  If you pass \$a (a reference to the $a scalar variable) to a subroutine, then in the subroutine the variable that receives that parameter receives a *reference* (or a "pointer") pointing to the $a scalar - if in the subroutine you want to change the value of the $a variable, then you must first "dereference" the reference that was passed in, and then assign a new value to that dereferenced reference.

There are 2 different notations that you can use for dereferencing references.  Assuming we pass these references to a subroutine
   1. \$a       is a reference to a scalar
   2. \@array_a is a reference to an array
   2. \%array_a is a reference to a hash

and the subroutine receives those references into these scalars
   1. $ref_scalar_a
   2. $ref_array_a
   3. $ref_hash_a

then these are the 2 different notations that the subroutine can use to see and change the values of the variables that the references point to.

   * I'll call this first notation the standard dereference
     notation - you basically surround the reference with curly
     braces, and then in front of the curly braces place the symbol
     for the data type($-scalar, @-array, @(not %)-hash) that the
     reference points to:
         print ${$ref_scalar_a}; ### Prints the value of the scalar
                                 ### that $ref_scalar_a points to.
         print @{$ref_array_a}[0]; ### Prints the value of the 1st
                                   ### element of the array that
                                   ### $ref_array_a points to.
         print @{$ref_hash_a}{'a'}; ### Prints the value of the hash
                                    ### element whose key is "a", of
                                    ### the hash that $ref_hash_a
                                    ### points to.

   * I'll call this 2nd notation the arrow dereference, since
     we use a symbol that looks like an arrow "->" - I'm not sure
     if/how to use this notation for references to scalars, but
     here is how to use it for dereferencing array and hash
     elements:
         print $ref_array_a->[0]; ### Prints the value of the 1st
                                  ### element of the array that
                                  ### $ref_array_a points to.
         print $ref_hash_a->{'a'}; ### Prints the value of the hash
                                   ### element whose key is "a", of
                                   ### the hash that $ref_hash_a
                                   ### points to.


I hope this answers more questions than it creates.  These examples that I've provided are just ones from my own personal experience - if you have questions about references, you should consult the perldocs documentation sited above.


Back to Perl FAQ Index
Back to Perl Forum

My Archive

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close