简体   繁体   中英

perl foreach loop in subroutine

I know the subroutine in perl pass arg by reference. But in the below code, the foreach loop in the subroutine should not be changing the value for @list because the my $i should be creating a new lexically scope var $i . Any assignment to $i should be lexically scope but not changing the @list value.

Can anyone explain what is happening inside the foreach loop that causes the value change to @list ?

sub absList {    
    foreach my $i (@_) {
        $i = abs($i);
    }
}

@list = (-2,2,4,-4);
absList(@list);
print "@list";

Outputs:

2 2 4 4

$i is aliased to elements of @_ array due foreach feature (and @_ elements are aliased to elements of the @list due @_ magic ).

From perldoc

If any element of LIST is an lvalue, you can modify it by modifying VAR inside the loop. Conversely, if any element of LIST is NOT an lvalue, any attempt to modify that element will fail. In other words, the foreach loop index variable is an implicit alias for each item in the list that you're looping over.

If you want to avoid such behavior, don't iterate directly over @_ array, ie.

sub absList {
    my @arr = @_;
    foreach my $i (@arr) {
        $i = abs($i);
    }
}

$i在这里引用它从@_获取的列表元素,这就是为什么更改$i会导致相应列表元素的更改。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM