[sf-perl] passing array and hash references
Rich Morin
rdm at cfcl.com
Thu Sep 28 12:08:55 PDT 2006
Clues, comments, suggestions?
-r
#!/usr/bin/env perl
#
# parm_test - test parameter passing methods
#
# Assume that you have a large body of code that was written
# in Perl 4, using typeglobs to pass arrays and hashes into
# functions. You want to kill off this ancient usage, moving
# to a method that complies with "use strict". However, code
# changes take effort and have associated risks. So, what is
# the "minimal cost" strategy for achieving your goals?
#
# Written by Rich Morin, rdm at cfcl.com, 2006.09
use warnings;
{
my (@array, %hash);
# Testbed: For each test function, assign some values,
# call the function, and print the (possibly
# updated) values.
$array[42] = 'a_val';
$hash{'42'} = 'h_val';
t_tg(\@array, \%hash); # uses typeglobs
print " array: ", $array[42], "\n";
print " hash: ", $hash{'42'}, "\n";
$array[42] = 'a_val';
$hash{'42'} = 'h_val';
t_ia(\@array, \%hash); # uses implicit arrows
print " array: ", $array[42], "\n";
print " hash: ", $hash{'42'}, "\n";
$array[42] = 'a_val';
$hash{'42'} = 'h_val';
t_ea(\@array, \%hash); # uses explicit arrows
print " array: ", $array[42], "\n";
print " hash: ", $hash{'42'}, "\n";
$array[42] = 'a_val';
$hash{'42'} = 'h_val';
t_dr(\@array, \%hash); # uses dereferencing
print " array: ", $array[42], "\n";
print " hash: ", $hash{'42'}, "\n";
}
# t_tg - test use of typeglobs
#
# Use of typeglobs to accept array and hash references is a
# Perl 4 hack. It does not work under "use strict".
#
sub t_tg {
(*array, *hash) = @_;
print "\nt_tg:\n";
print " array: ", $array[42], "\n";
print " hash: ", $hash{'42'}, "\n";
$array[42] = 'a_tg'; # Modifies passed parameter,
$hash{'42'} = 'h_tg'; # but fails "use strict".
}
# t_ia - test use of implicit arrows
#
# As I read Programming Perl (3rd. ed), these are equivalent:
#
# $$arrayref[2] $$hashref{'x'}
# $arrayref->[2] $hashref->{'x'}
#
# So, it should be possible to bring in references as function
# parameters and then treat them as if they were arrays or
# hashes. And, indeed, it works. Unfortunately, it does not
# comply with "use strict":
#
# Variable "@array" is not imported at parm_test line 81.
# Variable "%hash" is not imported at parm_test line 82.
# ...
#
sub t_ia {
my ($array, $hash) = @_;
print "\nt_ia:\n";
print " array: ", $array[42], "\n";
print " hash: ", $hash{'42'}, "\n";
$array[42] = 'a_ia'; # Modifies passed parameter,
$hash{'42'} = 'h_ia'; # but fails "use strict".
}
use strict;
# t_ea - test use of explicit arrows
#
# Bringing in references and using them with explicit arrow
# notation works and complies with "use strict". However, it
# requires editing quite a bit of code.
#
sub t_ea {
my ($array, $hash) = @_;
print "\nt_ea:\n";
print " array: ", $array->[42], "\n";
print " hash: ", $hash->{'42'}, "\n";
$array->[42] = 'a_ea'; # Modifies passed parameter.
$hash->{'42'} = 'h_ea'; # Ditto.
}
# t_dr - test use of dereferencing
#
# It's possible to bring in references, then dereference them
# and assign the result to arrays or hashes. This complies
# with "use strict", but it has two practical limitations. If
# the data structure is large, the overhead of copying it may
# be unacceptable. Worse, changes made to the copy will not
# affect the callers' data, so the changed code might not act
# in the same manner as the original code did.
#
sub t_dr {
my ($r_a, $r_h) = @_;
my (@array, %hash);
@array = @$r_a;
%hash = %$r_h;
print "\nt_dr:\n";
print " array: ", $array[42], "\n";
print " hash: ", $hash{'42'}, "\n";
$array[42] = 'a_dr'; # Modifies local data.
$hash{'42'} = 'h_dr'; # ditto
}
--
http://www.cfcl.com/rdm Rich Morin
http://www.cfcl.com/rdm/resume rdm at cfcl.com
http://www.cfcl.com/rdm/weblog +1 650-873-7841
Technical editing and writing, programming, and web development
More information about the SanFrancisco-pm
mailing list