Concerning the localizing of $_, that's the right thing to do in certain circumstances.
I'd argue that almost always that's the right thing to do. I'd say that it's an exception not to localize
$_, and so I really think that it should be put in demonstrative code--especially code targeting not-too-advanced Perl programmers. I'd go as far as putting a "Just do it unless you understand why you usually should do it and have a good reason not to" mark on this issue.
The result of not localizing
$_ would in practice be to do
$_ = undef, unless there's something that breaks out of the loop. The loop will continue until
$_ is undefined. If you actually want
$_ to be undefined after the loop then you're probably off better by explicitly undefining
$_ after the loop. Or you probably should ask yourself why you want to explicitly undefine it.
Afaik (but I have no safe source at the moment--and I started Perling right about v5.6's release so I have no own historical perspective),
foreach didn't use to localize its associated variable. At some time the porters (or whoever it was) decided that
foreach really ought to localize its variable. And I think everyone agrees that's a good thing. Why
while wasn't given the same treatment I can only speculate about. I find it somewhat likely though that constructs like the one below could've had anything to do with it. (If such decision-making ever took place.)
/pat/ or last while <FOO>;
print;
You could point out, though, (as a general remark) that it might be a good idea to use local $_
... and I sure will.
;) (Actually, this post isn't directly targeted towards you, as you seem to mostly agree with me.)
This is such a serious topic it's even been mentioned in
Sins of Perl Revisited.
Personally I'm quite paranoid against modules that are likely to use this particular while loop. I always (unless I'm familiar with the author and knows that such mistakes aren't likely to happen) check the source to make sure that the module won't make me scratch my head for hours and hours because of a destroyed
$_. Actually, I entertained myself for a little while looking for places of improper non-localization of
$_ in my Perl installation. Out of 1076 scanned .pm files I found 28 that matched the very simple pattern
/while \s* \(? \s* </x. Out of these 28 modules 13 (!) were not localizing
$_ properly. I checked all 28 modules briefly to make sure that the match was indeed code (not in quotes, pod, or what-not), and I also tried to see if
$_ was localized in the current subroutine, and if not if it was used in some particular way. (In Pod::Functions the code was at file scope, but I still marked it as improper use.) But I don't claim to be perfect, so some cases below might have legitimate reasons for not localizing
$_.
(It seems like the authors were consistent. Those that localized
$_ did that for all
whiles, whereas those that didn't localize for one case didn't localize for any case.)
ihb
Curious about the 13 modules?
__DATA__
D:\usr\lib\B.pm
271: while (<$output_fh>) {
D:\usr\lib\CGI.pm
409: while (<$fh>) {
D:\usr\lib\CPAN.pm
2776: NETRC: while (<$fh>) {
3052: push @lines, split /\012/ while <FH>;
4544: while (<$fh>) {
4720: while (<$pipe>){
4831: while (<$fh>) {
4884: while (<$fh>) {
5266: while (<$fh>) {
D:\usr\lib\CPAN\FirstTime.pm
549: while (<$fh>) {
D:\usr\lib\ExtUtils\Command.pm
57: print while (<>);
D:\usr\lib\ExtUtils\Manifest.pm
139: while (<M>){
175: while (<M>){
228: while (<F>) { $diff++,last if $_ ne <T>; }
D:\usr\lib\ExtUtils\MM_Unix.pm
1531: while (<FH>) {
1564: while (<FH>) {
2761: while (<FH>) {
2801: while (<FH>) {
D:\usr\lib\ExtUtils\MM_VMS.pm
206: while (<PM>) {
2158: while (<LIST>) {
2174: while (<OPT>) {
D:\usr\lib\Pod\Functions.pm
56: while (<DATA>) {
D:\usr\lib\Test\Harness.pm
97: while (<$fh>) {
D:\usr\site\lib\PPM.pm
218: while (<MAKEFILE>) {
D:\usr\site\lib\Tk\ColorEditor.pm
54: while(<FOO>) {
D:\usr\site\lib\Tk\TextUndo.pm
751: while (<FILE>)
782: while (<FILE>)