[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