bichonfrise74 has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I have this snippet. I basically just wants to read the content of __DATA__. But for some strange reason, sometimes it works and sometimes it doesn't because $_ seems to be picking up old values. I'm not sure why it should be doing this.

Or is there a better way to write this snippet?
use strict; my $test = qq(); $test = $test . $_ while (<DATA>); print "$test"; __DATA__ Hello there. This is me.

Replies are listed 'Best First'.
Re: __DATA__ Inconsistency
by moritz (Cardinal) on Oct 02, 2008 at 23:24 UTC
    You can write this as
    my $test = do { local $/; <DATA> }; print $test;

    See $/ for an explanation of what it does.

Re: __DATA__ Inconsistency
by GrandFather (Saint) on Oct 02, 2008 at 23:30 UTC

    I'd add in use warnings; as a matter of course, but that won't make any difference to your problem.

    I'd $test .= $_ while <DATA>;, but that won't make any difference either (although it means you don't need to init $test in the previous line).

    Rather than the while loop I'd more likely write: my $test = join '', <DATA>;, but that won't make any difference either (Update: actually if I were a couple more cups of coffee through the day I'd use $/ as moritz suggests).

    In fact, I can't see how the code you've shown could fail in the manner you describe. Does your sample code actually fail, or have you golfed it down from a larger piece of code that does fail? If the sample is golfed, try generating a sample that actually does fail and show us that.


    Perl reduces RSI - it saves typing
      It does fail and it would add in the $_ some messages that occurred early on, but again it is so inconsistent. I wish I could re-produce it.

      What I did was I "initialized" $_ to be safe.
      $test = qq(); $_ = qq(); $test = $test . $_ while(<DATA>);

        In your sample code there is no "early on". Show us the actual code that is failing rather than what you consider to be a representative snippet. The code you have shown can not fail in the way you describe!


        Perl reduces RSI - it saves typing
Re: __DATA__ Inconsistency
by cdarke (Prior) on Oct 03, 2008 at 04:59 UTC
    The only way I can get previous values of $_ printed is to slightly modify the loop:
    use warnings; use strict; my $test = qq(); $_ = 'xxxx'; do{$test = $test . $_ } while (<DATA>); print "$test"; __DATA__ Hello there. This is me.
    Are you perhaps doing that?
      It is very possible that I'm doing what you've just written. But the code is too long for me to post here. Anyway, thanks for all your inputs. I really appreciate it.
        do BLOCK while EXPR;

        is uniquely special case of

        EXPR while EXPR;

        The do variant is a bottom tested loop. The loop body will always execute at least once, and will do so before executing the condition expression.

Re: __DATA__ Inconsistency
by tmaly (Monk) on Oct 03, 2008 at 04:53 UTC
    try using tell and seek to debug issues with __DATA__ I ran into problems where I was reading from __DATA__ in a module multiple times and one the second read the position had moved to the bottom. However this may not be your case, but using tell to get the position and printing it out might shed some light.
Re: __DATA__ Inconsistency
by massa (Hermit) on Oct 03, 2008 at 02:11 UTC
    What you are calling "old values" are IMHO the "current values". Your first line came blank because, well, you put a blank line as the first line of __DATA__. delete the line between __DATA__ and Hello there. and all will work as you want :-)
    []s, HTH, Massa (κς,πμ,πλ)

      You are describing a "fix" to a deterministic behavior which you inferred to be the issue the OP is talking about. However the OP clearly states that his problem is non-deterministic - your fix is for the wrong issue.


      Perl reduces RSI - it saves typing