PPP
PPP

Reputation: 355

Perl: Substitution to 'foreach' local variable changed the elements of array used for 'foreach' processing

Code Snippet:

use File::Basename;
my @powerArray;
my $powerLoc = "/home/yuerki/10.12/proj";
@powerArray = glob("$powerLoc/*") if (-e $powerLoc);
print "FIRST: @powerArray is powerArray\n";
foreach my $powerNum (@powerArray) {
    $powerNum= basename ($powerNum);
    if($powerNum =~ /power/)
    {
        $powerNum =~ s/power//g;
        $powerNum  =~ s/\n//g;
        $powerNum =~ s/^\s+|\s+$//g;
        push(@powerList,"$powerNum") if ($powerNum =~ /^\d+$/);
    }
}
print "SECOND: @powerArray is powerArray\n";

Content inside "/home/yuerki/10.12/proj/" is : power1, power2, power3, power4, power5

Output:

FIRST: /home/yuerki/10.12/proj/power1 /home/yuerki/10.12/proj/power2 /home/yuerki/10.12/proj/power3 /home/yuerki/10.12/proj/power4 /home/yuerki/10.12/proj/power5 is powerArray

Second: 1 2 3 4 5 is powerArray

Question/Doubt: Why "SECOND: 1 2 3 4 5 is powerArray" has come in output? I was expecting it to be "SECOND: /home/yuerki/10.12/proj/power1 /home/yuerki/10.12/proj/power2 /home/yuerki/10.12/proj/power3 /home/yuerki/10.12/proj/power4 /home/yuerki/10.12/proj/power5" because we made no changes in @powerArray, and only in $powerNum?

Can anyone please explain? Also, how can i avoid the substitution changes in @powerArray? As I need to use this global array at other places as well

Upvotes: 1

Views: 81

Answers (2)

ikegami
ikegami

Reputation: 386706

Rather than copying the scalar for that interation, the foreach loop aliases the loop variable to it.

my $y = 123;
for my $x ( $y ) {
   $x = 456;
}

say $y;  # 456

Make a copy.

for ( @powerArray ) {
   my $powerNum = $_;
   ...
}

Or avoid modifying it.

push @powerList, basename( $powerNum ) =~ /^power(\d+)/;

Upvotes: 1

vkk05
vkk05

Reputation: 3222

Make modification like below:

...
@powerArray = glob("$powerLoc/*") if (-e $powerLoc);
print "FIRST: @powerArray is powerArray\n";
foreach my $element (@powerArray) {
    my $powerNum = $element;
    $powerNum= basename($powerNum);
    if($powerNum =~ /power/){
...

Hope this helps.

Upvotes: 2

Related Questions