Missing $ on loop variable
Asked Answered
A

6

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

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

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

Acquit answered 7/6, 2010 at 9:10 Comment(0)
S
8

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.

Susceptive answered 7/6, 2010 at 9:15 Comment(1)
This has changed since Perl v5.36. Iterate over multiple elements at the same timeCommutator
A
13

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.

Awesome answered 7/6, 2010 at 9:30 Comment(2)
does the first line creates a local copy of @array?Acquit
@k0re : It depends on the scope how local the copy is. @tmparray is not local to the while loop only.Markmarkdown
S
8

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.

Susceptive answered 7/6, 2010 at 9:15 Comment(1)
This has changed since Perl v5.36. Iterate over multiple elements at the same timeCommutator
E
5

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.

Emogene answered 7/6, 2010 at 14:33 Comment(0)
S
2

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";
}
Stoop answered 7/6, 2010 at 20:46 Comment(0)
V
1

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";
}
Valois answered 7/6, 2010 at 9:32 Comment(1)
the thing is to access more than one value at a time.Acquit
B
1

As of Perl version 5.36 released in 2022, you can iterate over multiple values at a time. For compatability with older versions, see @ysth's answer. https://perldoc.perl.org/perlsyn#Foreach-Loops

for my($a,$b,$c) (@array) { ... }
for my($key,$value) (%hash) { ... }
for my($key,$value) (%hash{sort keys %hash}) { ... } #sorted/consistent order
Bibliolatry answered 27/8, 2024 at 10:36 Comment(1)
This is a stable feature in v5.40, but before that you need use experimental qw(for_list); to activate it. Iterate over multiple elements at the same timeCommutator

© 2022 - 2025 — McMap. All rights reserved.