Ack, you're right (of course) ... for some reason I always think of $_ as a global. Still I find even the goto version nicer and the obvious change for the sub version turns it into the form you posted, but with the do as a sub (which is, again, more readable IMO).
| [reply] |
for some reason I always think of $_ as a global
Well, $_ is a global. That's not the reason it's failing though.
Perhaps you think that:
if (<HANDLE>) { ... }
assigns to $_? If so, that's your mistake. It doesn't. It reads a line, sees if it's true (not just defined, but true), and then tosses the line.
| [reply] [d/l] |
To amplify what merlyn said, the relevant quote from perlop is:
Ordinarily you must assign the returned value to a variable, 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" statement (even if disguised as a "for(;;)" loop), the value is automatically assigned to the global variable $_, destroying 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 $_ variable is not implicitly localized. You'll have to put a "local $_;" before the loop if you want that to happen.
However, I can not seem to find in the perl manual pages the explicit example from the Llama book (2nd edition):
Remember that this special magic requires a while loop. If you use the input operator anywhere else, you must assign the result explicitly if you want to keep the value:
if (<STDIN>) { print; } # WRONG, prints old value of $_
if ($_ = <STDIN>) { print; } # okay
It does feel weird to be quoting merlyn in a comment by merlyn. :)
| [reply] [d/l] |
Yes, I'd assumed that it was the scalar context that made it magic. Stupidly I'd thought about changing the if to a while before I posted, but decided it didn't matter ... ahh well, I may be slow but I've got there in the end. So...
sub next_record() {
local $/ = "DELIM";
while (<FILE>) { return 1; }
return 0;
}
while (next_record())
{
...
}
...is what I should have posted about 10 posts up the thread.
| [reply] [d/l] |