2

I am currently learning Perl and I want to pass an array to subroutine and print its content. I found that reference to array should be passed, however I am missing something:

arrayPrint($a,$b,\@array);

sub arrayPrint{
    my ($a,$b,@array) = @_;

    for(my $i=0; $i<=$#array;$i++){
        print $file $a.$b.$array[i]."\n";
    }
}
2
  • 1
    Tip: Don't use $a and $b; those are a bit special because of their use by sort. Commented May 25, 2022 at 15:37
  • 2
    Tip: for my $i (0..$#array) is a lot more readable than for (my $i=0; $i<=$#array; $i++). And since you don't need the index, for my $e (@array) is even more readable. Commented May 25, 2022 at 17:05

2 Answers 2

8

You can't pass arrays (or hashes) to subs. You can only pass scalars to subs. (And they can only return scalars.)

What we can do is pass a reference to an array (or hash). References are scalars. And in fact, this is what you are doing.

The problem is that you are assigning it to an array. An array that always contains exactly one scalar just makes things complicated for nothing. It should be assigned to a scalar. And it should be treated as a reference.

sub arrayPrint {
   my ( $x, $y, $array ) = @_;

   for my $e ( @$array ) {
      say $fh "$x$y$e";
   }
}

arrayPrint( $x, $y, \@array );

The other approach would be to pass each element of the array to the sub.

sub arrayPrint {
   my ( $x, $y, @array ) = @_;

   for my $e ( @array ) {
      say $fh "$x$y$e";
   }
}

arrayPrint( $x, $y, @array );

or

sub arrayPrint {
   my $x = shift;
   my $y = shift;

   for my $e ( @_ ) {
      say $fh "$x$y$e";
   }
}

arrayPrint( $x, $y, @array );
Sign up to request clarification or add additional context in comments.

Comments

5

Don't use the special variables $a and $b as lexicals, it can break sort.

Your code is sending an array reference to the subroutine, but populating an array with it. The @array inside the subroutine will have a single element: the array reference.

You can send the array directly, which will in effect send all its members as individual arguments (very bad if the array can be large).

Or, send the reference, but populate a scalar with it. You can't use $# directly with a reference, though, you need to dereference it.

my ($x, $y, $array_ref) = @_;
for my $i (0 .. $#{$array_ref}) {

It's more common to iterate over the elements rather than indices, though.

for my $e (@$array_ref) {

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.