Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I pass a reference to a subroutine?

References in Perl

How do I pass a reference to a subroutine?

by  hmerrill  Posted    (Edited  )
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.

Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top