The foreach loop is one of the most useful and commonly used loops in Perl. It allows you to iterate over lists of values and perform operations on each element. In this comprehensive guide, we will explore various examples of using foreach loops in Perl to master its usage.
Foreach Loop Basics
The basic syntax of a foreach loop in Perl is:
foreach my $element (@array) {
# code to execute
}
This loops through the @array list, assigning each value to the $element variable and executing the code block.
Some key points:
$elementcan be any variable name, this will contain the current value of the iteration@arrayis the list of values to iterate over- The code block inside
{ }runs once for each element in @array
You can iterate over arrays, hashes, files, input streams and more with foreach.
Iterating Arrays
Let‘s start with a simple example of iterating an array of numbers and printing each element:
my @numbers = (1, 2, 3, 4, 5);
foreach my $num (@numbers) {
print "Number: $num\n";
}
This will print out each number in the @numbers array. The $num variable contains the current array element value.
You can perform any operations on $num, like doing math calculations, string manipulation, etc.
For example, let‘s double each number:
foreach my $num (@numbers) {
my $doubled = $num * 2;
print "Double of $num is $doubled\n";
}
This iterates the array, doubles each number and prints it out.
Multidimensional Arrays
To iterate a 2D or multidimensional array, you access the child arrays like normal.
For example:
my @array2d = (
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
);
foreach my $child_array (@array2d) {
foreach my $num (@$child_array) {
print "$num ";
}
print "\n";
}
Here @$child_array iterates over the current child array reference in each iteration.
Hashes
To iterate over a hash, we use the keys and values functions:
my %hash = (
a => 1,
b => 2,
c => 3
);
foreach my $key (keys %hash) {
my $value = $hash{$key};
print "$key -> $value\n";
}
keys %hash returns the hash keys which we can iterate over and use to access hash values.
There is also a special %hash syntax to loop over both keys and values:
foreach my $key (keys %hash) {
foreach my $value (%hash) {
print "$key -> $value\n";
}
}
Iterating Files
A common use case for foreach loops is processing files line by line.
We open the file handle for reading with < and pass it to foreach:
open my $in_file, ‘<‘, ‘data.txt‘ or die $!;
foreach my $line (<$in_file>) {
print "$line";
}
This iterates over data.txt line by line, with each line in $line. We print out the lines as is.
Some ways to manipulate file content line by line:
chomp($line);– Remove newline charactersmy @fields = split(‘,‘, $line);– Split into fields by a delimiter$line =~ s/search/replace/;– Search and replace
You can open multiple files this way by passing all file handles to loop:
foreach my $line (<$file1>, <$file2>) {
...
}
This allows processing multiple files sequentially by line.
Custom Iterators
We are not limited to just arrays or hashes with foreach. You can create your own iterators using generator functions.
For example, this function returns an iterator for the sequence of Fibonacci numbers:
sub fib_seq {
my ($x, $y) = (1, 1);
while (1) {
yield $x;
my $next = $x + $y;
($x, $y) = ($y, $next);
}
}
To use this iterator:
foreach my $fib (fib_seq()) {
print "$fib ";
last if $fib > 100;
}
print "\n";
Here we iterate the numbers produced by fib_seq generator, stopping at 100.
This allows implementing any custom sequences/data logic to use with foreach.
Loop Controls
Some useful loop control statements are:
last
The last statement exits the loop immediately:
foreach (@array) {
last if $some_condition;
...
}
This stops iterating once $some_condition evaluates to true.
next
The next statement skips the rest of the current iteration and continues to next element:
foreach (@array) {
next if $_ < 5;
print "$_\n";
}
Here any element less than 5 is skipped.
redo
The redo statement restarts current iteration from the beginning.
For example:
foreach $line (@lines) {
redo if $line =~ /^\s*#/;
print "$line";
}
This skips comment lines starting with # by resetting the loop for that iteration.
Controlling lists
You can modify the list being iterated over within the loop using:
push @list, $new_element;– Add elementspop @list;– Remove last elementshift @list;– Remove first elementunshift @list, $new_element– Add to beginning
For example:
foreach (@files) {
if (-d $_) {
push @directories, $_;
shift @files;
}
}
This filters files into directories and non-directories dynamically.
So by modifying arrays/lists within foreach loops, you can precisely control iteration.
Iterating User Input
A useful technique is using foreach to repeatedly take user input and process it.
For example, a todo list app:
print "Enter todos, enter done to stop:\n";
foreach (1) {
print "Enter todo: ";
my $input = <STDIN>;
chomp($input);
last if $input eq ‘done‘;
push @todos, $input;
}
print "\nTodos:\n";
foreach (@todos) {
print "$_\n";
}
We use an infinite foreach loop along with last to keep reading user input. The input is collected in @todos array which we can print out.
This allows creating interactive CLI programs with foreach user input processing.
Foreach Style
Some Perl style guides recommend writing foreach loops in a more Perlish way:
Instead of:
foreach my $element (@array) {
}
Write as:
for my $element (@array) {
}
or even:
for (@array) {
my $element = $_;
}
Using the implicit $_ variable further reduces visual noise.
The functionality is identical in all styles, so choose whichever you prefer based on readability for your code.
Performance Considerations
-
Accessing array elements by index
$array[$i]is faster than by value with foreach. Use regular for loop if speed is critical. -
Deleting elements within loop using
shift/popcausesreindexing and is slower. Delete elements beforehand instead. -
Use lexical scope variables like
my $xinstead of global$xwhich is slower. -
Lower memory usage by processing iterated elements inside loop instead of pushing to another array.
Conclusion
Foreach loops provide a clean, concise and efficient way to iterate in Perl. They can manipulate arrays, hashes, files, user input and custom iterators.
We learned various examples like processing arrays multidimensionally, reading files,Taking user input, along with loop control statements.
By mastering foreach loops, you can write simpler code and accomplish tasks involving iteration much faster in Perl.


