in reply to reading __DATA__ more than once

I'd do the following:
{ my $offset; sub build_data { seek DATA, ($offset ||= tell DATA), 0; return [ <DATA> ]; } }

_____________________________________________________
Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a job (NYC-area)
s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Replies are listed 'Best First'.
Re: reading __DATA__ more than once
by ff (Hermit) on Nov 14, 2002 at 08:06 UTC
    Thank you! It hadn't occurred to me that the value landing in my $offset could persist through every time I entered the package to use its sub. Much less am I aware of the true workings of __DATA__ and using seek & tell to play with it. :-)

    As for "fast food", I'd say about 1% of the main program's data is accessed this way, 99% comes in traditional fat free ways. But "needs of the business" seem to require accessing this particular chunk of data in a more devious way... Are there side effects I should be aware of if I operate in this way? Besides its just being creepy?

      The value sticks around because I don't create in the function, but in the scope surrounding the function. If you've got Perl 5.6, here's a cooler way to do it:
      { my $offset; CHECK { $offset = tell DATA } sub data { seek DATA, $offset, 0; [<DATA>] } }
      The CHECK block happens just after compile-time ends.

      _____________________________________________________
      Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a job (NYC-area)
      s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re^2: reading __DATA__ more than once
by Aristotle (Chancellor) on Nov 15, 2002 at 23:22 UTC
    This is a case for applying tye's best practices:
    { my $offset; BEGIN { $offset = tell DATA } sub build_data { seek DATA, $offset, 0; return [ <DATA> ]; } }

    That way, even if someone else touches DATA before build_data is called the first time (aka a race condition), it still produces the correct result.

    Update: Good point - I stand corrected.

    Makeshifts last the longest.

      You cannot use BEGIN there. See my response earlier, where I do a very similar solution. I use CHECK instead (because Perl has not seen the __DATA__ marker yet, if you use BEGIN).

      _____________________________________________________
      Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a job (NYC-area)
      s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;