Take the 2-minute tour ×

I know that this is probably a simple fix, but I have not been able to find the answer through google and searching through the questions here.

My goal is to pass multiple arrays to a subroutine that simply iterates through each array separately and prints each array with something before and after it.

What I have:

@A1 = (1, 2, 3);
@A2 = (4, 5, 6);

printdata(@A1, @A2) ;

sub printdata {
   foreach(@_) {
      print "$_" ; 
      print "@@@"

What I am attempting to get is:


Instead its treating both arrays as one and iterating through each variable in the array, Putting the separator after every variable vice the entire array.


I am not sure how to get the subroutine to treat the arrays as separate rather than as one.

Any Help would be greatly appreciated!

share|improve this question
What you've discovered is the List context in Perl. Lists are what get passed to methods (and almost any time you do use a paren with commas inside). They automatically flatten anything inside of them - arrays or hashes. This can be really convenient when passing arguments to functions (eg, you can build up all the arguments in an array, then pass it as a list to the function) or collating data from multiple sources (such as combining multiple hashes or arrays), but this idea of 'context' is new to most programmers and so can trip people up. :) –  Robert P Jun 29 '11 at 16:20

3 Answers 3

up vote 6 down vote accepted

You need to pass the arrays as references:

@A1 = (1, 2, 3);
@A2 = (4, 5, 6);

printdata(\@A1, \@A2) ;

sub printdata {
   foreach(@_) {
      print @$_ ; 
      print "@@@"

The sub call expands the arrays into a list of scalars, which is then passed to the sub within the @_ variable. E.g.:

printdata(@A1, @A2);

is equal to:

share|improve this answer
Perfect thanks, I knew I was missing something simple. I don't exactly understand references, but I will be researching it now. –  Kevin Jun 29 '11 at 15:15
Its not simple, by adding "\" he introduced a new concept of perl programming which is very different from your concept –  mac Nov 11 '11 at 7:22

See the section on "Pass by Reference" in perldoc perlsub.

share|improve this answer
+1 for nice documentation link –  TLP Jun 29 '11 at 12:30
Teaching to fish :-) –  Dave Cross Jun 29 '11 at 12:45
But what about the fishers? ;) –  TLP Jun 29 '11 at 12:51
use strict;
use warnings;
use English qw<$LIST_SEPARATOR>;

my @A1 = (1, 2, 3);
my @A2 = (4, 5, 6);
{   local $LIST_SEPARATOR = '';
    my @a = map { "@$_" } \@A1, \@A2;
    $LIST_SEPARATOR = '@@@';
    print "@a\n";

You also could have used join (po-tay-to, po-tah-to).

my @a = map { join( '', @$_ ) } \@A1, \@A2;
print join( '@@@', @a ), "\n";
share|improve this answer
I like the use of the somewhat obscure continue: for (@_) { print @$_ } continue { print "@@@" } –  TLP Jun 29 '11 at 12:49
@TLP, Cool!. I have never used continue, it has always looked like an ugly tack-on--probably a bias coming from other languages. I might need to reconsider. –  Axeman Jun 29 '11 at 13:06
I've never used it either. ;) I just thought this was a fun opportunity to try it out. Easy mnemonic: It does the same as the third element in a c-style for loop, for (init; inc; *continue*) –  TLP Jun 29 '11 at 13:09

Your Answer


