Re: a question about for and foreach



rainman wrote:
Hi,

Hello,

I got a very strange problem about for and foreach. I don't
understand why.

The following is my program:

===
#!/usr/bin/perl

use strict;

my @array = (1, 2, 3);
print @array;

foreach (@array) {
print $array[0];
print $array[1];
print $array[2];
open FILE, "<bbb";
while (<FILE>) {
print "hello\n";
}
close FILE;
}

print @array;
print $array[1];
===

"bbb" just a file contains only one line like "kdfjkdfjlsjfslkf".

My question is, why @array are changed after this foreach loop!!!

The documentation from perlsyn.pod:

perldoc perlsyn
[ SNIP ]
Foreach Loops

The "foreach" loop iterates over a normal list value and sets the
variable VAR to be each element of the list in turn. If the
variable is preceded with the keyword "my", then it is lexically
scoped, and is therefore visible only within the loop. Otherwise,
the variable is implicitly local to the loop and regains its former
value upon exiting the loop. If the variable was previously
declared with "my", it uses that variable instead of the global one,
but it’s still localized to the loop. This implicit localisation
occurs only in a "foreach" loop.

The "foreach" keyword is actually a synonym for the "for" keyword,
so you can use "foreach" for readability or "for" for brevity. (Or
because the Bourne shell is more familiar to you than csh, so
writing "for" comes more naturally.) If VAR is omitted, $_ is set
to each value.

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.

What your program does:

foreach $_ (@array) {
open FILE, "<bbb";
while ($_ = <FILE>) {
print "hello\n";
}
close FILE;
}

So $_ is an alias to the current element of @array and the while loop assigns to $_ which changes the current value of that element.

What you should do:

foreach my $item ( @array ) {
open FILE, '<', 'bbb' or die "Cannot open 'bbb' $!";
while ( my $line = <FILE> ) {
print "hello\n";
}
close FILE;
}



John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall

.



Relevant Pages

  • Re: Optimisation for tight loops...
    ... my $searchfor = 99999; ... foreach { ... entire array using grepfor instance. ... loop, at least in comparison to the C_style method. ...
    (comp.lang.perl.misc)
  • Re: foreach statement output
    ... by using a 'for' statement instead of the foreach loop: ... and I will use the array to generate a string. ... know about foreach loop workings. ...
    (comp.infosystems.www.authoring.cgi)
  • Re: Parallel programming with FORALL?
    ... forall and perl's 'foreach'? ... An example from _Learning Perl_ p. 47 is: ... command is used as values for the loop variable. ... Now, notice that it loops over the values of the array elements, ...
    (comp.lang.fortran)
  • Re: foreach statement output
    ... know about foreach loop workings. ... I've got an incoming array of unknown ... The Perl Cookbook ... My big confusion over this foreach issue is I failed to realize that the ...
    (comp.infosystems.www.authoring.cgi)
  • Re: tr operator weirdness
    ... You need to read about foreach loops. ... If any element of LIST is an lvalue, you can modify it by ... modifying VAR inside the loop. ...
    (comp.lang.perl.misc)