in reply to File::Slurp bug? Should I bother?

Thanks for the replies so far. My version is 9999.09, which is current. Passing the binmode parameter doesn't change anything.

Here is another test:

use strict; use warnings; use File::Slurp; my $file_slurp = read_file('file'); my $normal; { local $/; open my $FILE, '<', 'file' or die $!; $normal = <$FILE>; close $FILE; } write_file('slurp', $file_slurp); open my $NORMAL, '>', 'normal' or die $!; print $NORMAL $normal; close $NORMAL; open my $SLURP_NORMAL, '>', 'slurp_normal' or die $!; print $SLURP_NORMAL $file_slurp; close $SLURP_NORMAL;

Doing this, both normal and slurp end up with the file identical to the original, but slurp_normal has the "added" newlines. So something in File::Slurp is "correcting" whatever it did to begin with when I use write_file. I'm puzzled.

Replies are listed 'Best First'.
Re^2: File::Slurp bug? Should I bother?
by ikegami (Patriarch) on Sep 07, 2005 at 17:02 UTC

    I installed File::Slurp and I can't reproduce your results. What do you get when you run the following? File::Slurp should remove carriage returns by default.

    use strict; use warnings; use File::Slurp qw( read_file ); my $f = 'testdata'; { open(my $fh, '>', $f) or die $!; print $fh ("line1\n"); print $fh ("line2\n"); print $fh ("line3\n"); } { print("Disk size: "); print((stat($f))[7], "\n"); print("\n"); print("Inlined, binmode: "); print(length(do { local $/; open(my $fh, '<', $f) or die $!; binmode($fh); <$fh> }), "\n"); print("Slurp, binmode: "); print(length(read_file($f, binmode => 1)), "\n"); print("\n"); print("Inlined, not binmode: "); print(length(do { local $/; open(my $fh, '<', $f) or die $!; <$fh> }), "\n"); print("Slurp, not binmode: "); print(length(read_file($f, binmode => 0)), "\n"); print("\n"); print("Slurp: "); print(length(read_file($f)), "\n"); } print("\n"); print("\n"); { my $inline = do { local $/; open(my $fh, '<', $f) or die $!; <$fh> }; my $slurp = read_file($f); if ($inline eq $slurp) { print("Slurp is indentical to inlined version.\n"); } else { print("Slurp is different from inlined version.\n"); } }

    You should get the following, exactly:

    Disk size: 21 Inlined, binmode: 21 Slurp, binmode: 21 Inlined, not binmode: 18 Slurp, not binmode: 18 Slurp: 18 Slurp is indentical to inlined version.

    Environment:

    >perl -MFile::Slurp -le "print $File::Slurp::VERSION" 9999.09 >perl -v This is perl, v5.6.1 built for MSWin32-x86-multi-thread (with 1 registered patch, see perl -V for more detail) ...
      Disk size: 21 Inlined, binmode: 21 Slurp, binmode: 21 Inlined, not binmode: 18 Slurp, not binmode: 21 Slurp: 21 Slurp is different from inlined version.

      C:\>perl -MFile::Slurp -le "print $File::Slurp::VERSION" 9999.09 C:\>perl -v This is perl, v5.8.6 built for MSWin32-x86-multi-thread (with 3 registered patches, see perl -V for more detail)

      Blarg, OK, this may be a problem with sysread.

      use strict; use warnings; use Fcntl qw{:DEFAULT}; use Data::Dump qw{dump}; sysopen my $FILE, 'file', O_RDONLY or die $!; my ($temp, $buf); while(1) { my $read_cnt = sysread ($FILE, $temp, 1024); $buf .= $temp; last unless $read_cnt; } print dump($buf);
      This gives me the faulty newlines. I think this is a bug in my Perl build. Google turned up some (vague) results to that effect. I assume sysread is supposed to do CRLF translation to \n, just like <>? I checked, and the layers in effect on this filehandle are ("unix", "crlf"). Should be working.

        I just experimented a little using

        This is perl, v5.6.1 built for MSWin32-x86-multi-thread
        -> sysread convert CRLF to LF.

        This is perl, v5.8.0 built for MSWin32-x86-multi-thread
        -> sysread does **not** convert CRLF to LF.

        Both are ActiveState builds.

        Apparently, sysopen/sysread's behaviour changed in 5.8 wrt to CRLF conversion. It used to convert, but now it doesn't. I don't see this mentioned in Perl 5.8's perldelta or anywhere else. It seems to be an (unintentional?) side-effect of switchting to PerlIO.