http://qs321.pair.com?node_id=64950


in reply to Re: What would you do?
in thread What would you do?

Not quite. The first method does not assign to the same $_ that the while loop uses. If it did, you couldn't use $_ in that for loop at all.
while (<FH>) { # localized $_ for (split ' ') { # localized $_ } # previous $_ }
It's when you start doing silly and dangerous things like:
sub foo { $_ = shift; # TSK! local $_ tr/aeiou/AEIOU/; return $_; }
that problems occur. It is a bad idea to assign to a global $_ -- where "global" means "not localized".

japhy -- Perl and Regex Hacker

Replies are listed 'Best First'.
Does while localize $_?
by tenya (Beadle) on Mar 18, 2001 at 22:40 UTC
    Your comment and several others I have seen here suggest that while(FH) and foreach automatically localize $_. But the folowing code seems does not revert to the old $_ after leaving the while loop. What am I missing? Thanks.
    use strict; use diagnostics; $_ = "Before"; print "Before loop= $_\n"; while (<>){ print "In while loop= $_\n"; last; } print "After while loop= $_\n"; Output: Before loop= Before myinput (entered from the keyboard) In while loop= myinput After while loop= myinput

      A foreach loop does implicitly localize $_ (or whatever variable is being used as the loop variable), but $_ is not automatically localized for while(<>) loops. Here is the relevant entry from the perlop manpage:

      Ordinarily you must assign the returned value to a vari- able, but there is one situation where an automatic assignment happens. If and only if the input symbol is the only thing inside the conditional of a `while' state- ment (even if disguised as a `for(;;)' loop), the value is automatically assigned to the global variable $_, destroy- ing whatever was there previously. (This may seem like an odd thing to you, but you'll use the construct in almost every Perl script you write.) The $_ variables is not implicitly localized. You'll have to put a `local $_;' before the loop if you want that to happen.

      However, that last line is misleading: you'll need to wrap it all in a block, or localize $_ in the while condition to get the proper effect:

      { local $_; while(<>){ print; } } # or, while(local $_ = <>) { print; }
        Which is helpful because this allows while loops inside the foreach loop to use the foreach $_. Correct?