in reply to Re: •Re: Seeking an idiom for localizing $/
in thread Seeking an idiom for localizing $/

sub next_record() { local $/ = "DELIM"; if (<FILE>) return 1; return 0; } while (next_record()) { ... }
Well my code may "look horrible" to you, but at least it works. Your code, on the other hand, simply tosses away the record being read. No assignments to $_ there, as you would need.

-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply.

Replies are listed 'Best First'.
Re: •Re: Re: •Re: Seeking an idiom for localizing $/
by nevyn (Monk) on May 04, 2004 at 18:37 UTC

    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).

    --
    James Antill
      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.

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

        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. :)

        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.

        --
        James Antill