How to use join?

Minimal code based on this answer and its join statement

my @x = qw/10 20 30 40/;
my @y = qw/60 70 8 90 10/;
my @input_list = (@x, @y);

print "Before join @input_list \n";

print join ",", @$_ for @input_list ;

print "After join @input_list \n";

which gives

Before join 20 40 60 80 120 140 16 180 20 
After join 20 40 60 80 120 140 16 180 20 

but in use strict;

Can't use string ("10") as an ARRAY ref while "strict refs" in use at test4.pl line 10.

join joins separate strings of array in manual. Here the code tries to join comma apparently with each hash (@$_) of the array item. However, this seems to be happening.

Why is this error here in the minimum code?

Upvotes: 2

Views: 130

Answers (2)

Sobrique
Sobrique

Reputation: 53478

OK, what you're doing here:

print join ",", @$_ for @input_list ;

Isn't working, because it's:

  • iterating @input_list extracting each element into $_.
  • Dereferencing $_ pretending it's an array @$_.

This is basically the same as trying to:

print join ( ",", @{"10"} );

Which makes no sense, and so doesn't work.

my $string = join ( ",", @input_list );
print $string; 

Will do the trick.

The thing that you're missing here I think, is this:

use Data::Dumper; 
my @x = qw/10 20 30 40/;
my @y = qw/60 70 8 90 10/;
my @input_list = (@x, @y);
print Dumper \@input_list;

Isn't generating a multi-dimensional list. It's a single dimensional one.

$VAR1 = [
          '10',
          '20',
          '30',
          '40',
          '60',
          '70',
          '8',
          '90',
          '10'
        ];

I suspect what you may want is:

my @x = qw/10 20 30 40/;
my @y = qw/60 70 8 90 10/;
my @input_list = (\@x, \@y);

Or perhaps:

my $x_ref = [ qw/10 20 30 40/ ];
my $y_ref = [ qw/60 70 8 90 10/ ];
my @input_list = ($x_ref, $y_ref );

Which makes @input_list:

$VAR1 = [
          [
            '10',
            '20',
            '30',
            '40'
          ],
          [
            '60',
            '70',
            '8',
            '90',
            '10'
          ]
        ];

Then your 'for' loop works:

print join (",", @$_),"\n" for @input_list ;

Because then, @input_list is actually 2 items - two array references that you can then dereference and join.

As a slight word of warning though - one of the gotchas that can occur when doing:

my @input_list = (\@x, \@y);

Because you're inserting references to @x and @y - if you reuse either of these, then you'll change the content of @input_list - which is why it's probably better to use the my @input_list = ( $x_ref, $y_ref );.

Upvotes: 7

RobEarl
RobEarl

Reputation: 7912

my @x = qw/10 20 30 40/;
my @y = qw/60 70 8 90 10/;
my @input_list = (@x, @y);

This is equivalent to:

my @input_list = qw/10 20 30 40 60 70 8 90 10/;

To create an array of arrays, use references:

my @input_list = (\@x, \@y);

The rest of your code then works as expected.

Upvotes: 4

Related Questions