3

I have the following Perl script.

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my @fruits = qw(apple banana orange pear);

print Dumper \@fruits;

foreach my $fruit (@fruits) {
  $fruit =~ s|apple|peach|;
}

print Dumper \@fruits;

The following is returned.

$VAR1 = [
          'apple',
          'banana',
          'orange',
          'pear'
        ];
$VAR1 = [
          'peach',
          'banana',
          'orange',
          'pear'
        ];

I do not understand why the following line has changed apple to peach in the @fruits array, as I thought this line would only apply to the $fruit variable, not the @fruits array.

$fruit =~ s|apple|peach|;
JeremyCanfield
  • 633
  • 11
  • 24

1 Answers1

5

In the html doc of perl we have the following statement for foreach loops:

the foreach loop index variable is an implicit alias for each item in the list that you're looping over

This means, you do not get a copy of each array element. The variable $fruit is only a reference to an array element. Its value can be modified if the array element can be modified. The modification applies to the original array element.

Donat
  • 4,157
  • 3
  • 11
  • 26
  • 1
    Got it, makes sense now. Within the foreach loop, I will define `my $inner = $fruit;` and then apply the modification to the $inner variable `$inner =~ s|apple|peach|g;`. Thanks much for the assistance here! – JeremyCanfield Jul 30 '21 at 11:54
  • 2
    You could use the `/r` regex modifier to do it in one go, e.g. `my $inner = $fruit =~ s|apple|peach|gr;` (although I find `s{apple}{peach}gr` a more readable way personally)) – David Precious Jul 30 '21 at 13:54
  • If you did get a copy, the code would do nothng – ikegami Jul 30 '21 at 20:20