On Wed, 24 Nov 1999 22:33:55 -0800
    "John S. Evans" <[EMAIL PROTECTED]> wrote
    in <[EMAIL PROTECTED]>:

>> From: "Eric L. Brine" <[EMAIL PROTECTED]>
>> 
>> A few days ago, someone mentioned doing
>> $scalar = <STDIN>
>> read the whole POSTed data.

>I was the guy :)

>Strange, because the "Writing Apache Modules..." book explicitly tells you
>that you CAN do this (use <STDIN> to read the post line by line).

>Based on my experience, and your snippet [above], I'm guessing the book is
>incorrect :)

The angle operator is subject to the $/ variable's current setting, per
perlvar(1) and perlop(1).  Only when that variable's value is undef do
you get the whole remainder of the input handle available as a single
scalar value.

      % man perlfaq5
      ...
      How can I read in an entire file all at once?

        The customary Perl approach for processing all the lines in a
        file is to do so one line at a time:

            open (INPUT, $file)         || die "can't open $file: $!";
            while (<INPUT>) {
                chomp;
                # do something with $_
            } 
            close(INPUT)                || die "can't close $file: $!";

        This is tremendously more efficient than reading the entire
        file into memory as an array of lines and then processing it
        one element at a time, which is often--if not almost always--the
        wrong approach. Whenever you see someone do this:

            @lines = <INPUT>;

        You should think long and hard about why you need everything
        loaded at once. It's just not a scalable solution. You might
        also find it more fun to use the the standard DB_File module's
        $DB_RECNO bindings, which allow you to tie an array to a file
        so that accessing an element the array actually accesses the
        corresponding line in the file.

        On very rare occasion, you may have an algorithm that demands
        that the entire file be in memory at once as one scalar. The
        simplest solution to that is:

            $var = `cat $file`;

        Being in scalar context, you get the whole thing. In list context,
        you'd get a list of all the lines:

            @lines = `cat $file`;

        This tiny but expedient solution is neat, clean, and portable
        to all systems that you've bothered to install decent tools
        on, even if you are a Prisoner of Bill. For those die-hards
        PoBs who've paid their billtax and refuse to use the toolbox,
        or who like writing complicated code for job security, you can
        of course read the file manually.

            {
                local(*INPUT, $/);
                open (INPUT, $file)     || die "can't open $file: $!";
                $var = <INPUT>;
            }

        That temporarily undefs your record separator, and will
        automatically close the file at block exit. If the file is
        already open, just use this:

            $var = do { local $/; <INPUT> };

--tom

Reply via email to