[Brisbane-pm] Passing a Two-Dimensional Array to a sub in Perl 5.8.6

Damian James djames at thehub.com.au
Wed Feb 21 23:54:59 PST 2007


On 22/02/2007, at 12:59 PM, Robert Loomans wrote:
>
> Personally, if I'm using multiple args in a sub, I do something like:
>
> sub Rain_calculation {
>     my ($zero, $one, $two, $three, $four, $five) = @_;
>
>     do_something($five->[0]);
>
>     foreach my $elem (@$five) {
>
> (where $zero ... $five would have more meaningful names).

I'm more likely to use a hash, for the same reasons.

Sending the args just as a plain hash would look like this:

my %foo = (
     bar => 42,
     baz => [ [1,2],[2,2],[2,1],[1,1]]
);
do_stuff(%foo);

   sub do_stuff {
      my %stuff = @_;
      print "$_ = $stuff{$_}\n" for qw/ bar /;
      print "@{ $_ }\n" for @{ $stuff{baz} };
}

Of course, it's possible to pass the hash by reference too:

  do_stuff( \%foo );
  sub do_stuff {
   #the either:
    my %stuff = %{ $_[0] };
   #or just refer to the elements by reference:
    print "@{$_}\n" for @{ $stuff->{baz} };
  }
> That way you aren't dealing with meaningless references to $_[x] that
> make the code really difficult to read, and the array you passed in  
> via
> $five is not copied....

Sometimes you just want the reference and sometimes, of course, you  
want the copy. It's worth pointing out for the OP's benefit what the  
difference is:

   my $x = [  0..99 ];  # If that's unfamiliar syntax, imagine it was  
"my @w = ( 0..99 ); my $x = \@w;"
   my $y = $x;
   my @z = @$x;

$x is a reference to an anonymous array, containing 0 to 99. $y gets  
the value of $x, which is the reference, so $y is actually a  
reference to the same array. Doing, eg, $y->[50]++, means that $x-> 
[50] is now 51. @z is a copy of the data in the array referred to in  
$x and $y, so you can do stuff to @z without affecting $x.

Generally in subs that do some manipulation of data and then return  
the result, you want to make a copy. In subs that return a result,  
but don't need to do any manipulation to the input data, you use a  
reference to avoid any (usually quite insignificant anyway) memory  
overhead. You are best advised to avoid the third case, subs that  
take a reference and change the data through it. There's a whole  
realm of obscure bugs that you invite into your system when you do  
this so called "long distance" data manipulation. Sure, half the  
Win32 API works like that, but those aren't people you want to  
emulate...

Anyway, there's a bunch of helpful material about references in the  
perl documentation, see perlreftut for instance.

Cheers,
Damian


More information about the Brisbane-pm mailing list