[sf-perl] passing array and hash references

David Fetter david at fetter.org
Thu Sep 28 12:18:06 PDT 2006


On Thu, Sep 28, 2006 at 12:08:55PM -0700, Rich Morin wrote:
> Clues, comments, suggestions?

Um, what is it that you want the above on?  I generally pass
references into functions, and increasingly just one reference to a
hash (named parameters) per Perl Best Practices. :)

Cheers,
D
> -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
> _______________________________________________
> SanFrancisco-pm mailing list
> SanFrancisco-pm at pm.org
> http://mail.pm.org/mailman/listinfo/sanfrancisco-pm

-- 
David Fetter <david at fetter.org> http://fetter.org/
phone: +1 415 235 3778        AIM: dfetter666
                              Skype: davidfetter

Remember to vote!


More information about the SanFrancisco-pm mailing list