Alberto E. Alberto E. - 21 days ago 5
Perl Question

Referencing and printing a 2D array in Perl

I've been reading about how you can't have an array of arrays in Perl thus I ended up struggling with references of arrays and I think I figure out how to return the array from a subroutine. However I can't get it to print the entire array after the return. Can someone explain to me why or how to debug this issue? It would be really appreciated indeed!

#!/usr/bin/perl
use strict;
use warnings;

#Subroutine to randomize the 2D Array:
sub randPattern {
my ($rand_ref) = @_;
my @RandBoard = @$rand_ref;

for (my $i = 0; $i <= $#RandBoard; $i++) {
for (my $j = 0; $j <= $#RandBoard ; $j++) {
$RandBoard[$i][$j] = 0 + int(rand(3 - 0));
print "$RandBoard[$i][$j] ";
}
print "\n";
}

return @RandBoard;
}

my @checkerArr = (
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0]
);

my ($randomizedArr_ref) = randPattern(\@checkerArr); #sending arrayy as reference
my @randomizedArr = @$randomizedArr_ref; #dereferencing the returned array
print "___________________\n";

foreach (@randomizedArr){
print "$_ "; }
print "\n";


And the output is like this:

1 1 1 1 1 0 2 1
1 0 0 0 2 2 0 1
2 1 1 2 1 2 0 1
1 2 0 2 0 1 0 1
1 2 1 2 0 0 1 0
2 1 0 1 0 0 0 2
2 2 0 0 0 2 0 0
1 1 1 0 0 1 1 1
___________________
1 1 1 1 1 0 2 1


As you can see it only outputs the first row of the array.

Answer

First, let me fix your code, then I'll explain...

#!/usr/bin/perl
use strict;
use warnings;

#Subroutine to randomize the 2D Array:
sub randPattern {
my ($rand_ref) = @_[0];
my @RandBoard = @$rand_ref;

for (my $i = 0; $i <= $#RandBoard; $i++) {
  for (my $j = 0; $j <= $#RandBoard ; $j++) {
     $RandBoard[$i][$j] = 0 + int(rand(3 - 0));
     print "$RandBoard[$i][$j] ";
   }
   print "\n";
  }

return @RandBoard;
}

my @checkerArr =  (
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0]
);

my ($randomizedArr_ref) = [randPattern(\@checkerArr)]; #sending arrayy as reference
my @randomizedArr = @$randomizedArr_ref; #dereferencing the returned array
print "___________________\n";

foreach (@randomizedArr){
    print(join(' ',@$_),"\n");
}

The main issue here is scalar context versus list context. You're returning a list from your subroutine and assigning that returned list in a scalar context ($randomizedArr_ref). You were getting an array reference (which was actually the last element of your outer array. You need to evaluate the return of the method in list context, so I added the square brackets around your method call ([randPattern(\@checkerArr)]).

I also added [0] to your setting of the parameter in the subroutine, which is a similar oversight. You were only getting the whlole parameter because you were passing in a single scalar (reference to an array).

Oh, and in your loop, I added a dereference of the array and joined with a space. I also moved the newline into the loop.