views:

180

answers:

5

Hi,

  1 #!/usr/bin/perl
  2 use strict;
  3 use warnings;
  4 
  5 my @array = qw[a b c];
  6 foreach my($a,$b,$c) (@array) {
  7     print "$a , $b , $c\n";
  8 }

I receive following error: Missing $ on loop variable What is wrong?

I am using: perl v5.10.1 (*) built for x86_64-linux-thread-multi

+7  A: 

I'm not aware that foreach can eat up more than one parameter at a time in Perl. I might be reading the documentation wrong.

ivans
You are right. http://dev.perl.org/perl6/rfc/173.html
name
+13  A: 

To grab multiple list items per iteration, use something like List::MoreUtils::natatime or use splice:

my @tmparray = @array; # don't trash original array
while ( my ($a,$b,$c) = splice(@tmparray,0,3) ) {
    print "$a , $b , $c\n";
}

Or reorganize your data into multiple arrays and use one of the Algorithm::Loops::MapCar* functions to loop over multiple arrays at once.

ysth
does the first line creates a local copy of @array?
name
@k0re : It depends on the scope how local the copy is. `@tmparray` is not local to the `while` loop only.
Zaid
@k0re: a shallow copy, yes
ysth
A: 

I think you are missing the point of foreach loop. It goes through every value in an array. It handles one value at a time. Here's the correct code:

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

my @array = qw[a b c];
foreach my $z (@array) {
    print "$z\n";
}
Jacek
the thing is to access more than one value at a time.
name
+4  A: 

As mentioned in the other answers, Perl does not directly support iterating over multiple values in a for loop. This is one of the issues I addressed in my module List::Gen:

use List::Gen;

my @array = qw/a b c d e f/;

for (every 3 => @array) {
    print "@$_\n";
}

outputs:

a b c
d e f

Edit: The list slices that List::Gen produces are aliased to the original list, so that means you can change values in the slice to change the original list. That functionality does not seem possible with several of the other solutions posted for this question.

Eric Strom
+2  A: 

Block::NamedVar provides nfor that DWIM. This is more convenient than the alternative ways to iterate.

use Block::NamedVar;

my @array = qw[a b c];
nfor my($a,$b,$c) (@array) {
    print "$a , $b , $c\n";
}
Schwern