[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