Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
There is one important things to note about foreach and while loops, namely the localization of the loop variable.

The foreach loop will always localize its loop variable (That is $_ unless one is spesified). This can easily be verified:

$_ = 42; foreach (1, 2, 3) { print "Inside loop: \$_ = [$_]\n"; } print "Outside loop: \$_ = [$_]\n";
This will print
Inside loop: $_ = [1]
Inside loop: $_ = [2]
Inside loop: $_ = [3]
Outside loop: $_ = [42]
The while loop however, does not localize anything. This can be seen from the following example
$_ = 42; while(<FH>) { print "Inside loop: \$_ = [$_]"; } print "Outside loop: \$_ = [$_]\n";
If <FH> produces three lines containing the digits 1, 2 and 3 the output will be
Inside loop: $_ = [1]
Inside loop: $_ = [2]
Inside loop: $_ = [3]
Outside loop: $_ = []
It will also produce a warning if you remembered to turn on the -w flag. Why the warning you might ask. The reason is because the <FH> will return undef when it has reached the end of the file, and $_ is assigned this undef. And as we all know, perl will warn us if we use an undefined value (if the -w flag is used).

So then, what is it that happens in your program ? First, let's just simplify it a little bit (concentrating on the first foreach loop):

foreach (@test_array) { print qq|Before while: [$_]\n|; open(IN, $0) || die "No file: $!\n"; while (<IN>) { } close IN; print qq|After while: [$_]\n|; }
Now, what happens is that the foreach loop creates spesial references into the @test_array. (Spesial in the sense that when you change $_, you also change the corresponding element in the @test_array)

The next line should then print out the value of $_, which in your example would be "Element1". Then we open ourself, and loop over each line in the file. The while (<IN>) construct implicitply assigns the $_ without first localizing it. Thus we actually change the elements of the array @test_array.

If you instead had used a foreach loop to iterate over the file, this problem would not have occured, because of the fact that it would have localized the $_ variable for you. Or you could localize $_ yourself by writing local $_. Another possible solution is to use lexical variables both in the foreach loop and in the while loop

foreach my $elem (@test_array) { open(IN, $0) || die "No file: $!\n"; while( defined(my $line = <IN>) ) { } close IN; }
(The defined test isn't really necessary in newer perls, but I like to be explicit here).

"But", I hear you complain, "my while loop is in a different function, a completly new scope". Well, that is correct if you are talking about lexical scoping (variables declared with the my keyword are lexical variables). However, $_ is a dynamically scoped variable (this fact you can't change, you can't declare my $_. Here is a good tutorial explaining the difference between a lexical scope and a dynamic scope.) However, since $_ is dynamically scoped, it will live on in the new function only to be assigned by the while loop.

I hope this shed some light on the problem at hand.

Autark.


In reply to Re: What Is Going On Here ????? by autark
in thread What Is Going On Here ????? by orthanc

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2024-04-25 08:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found