http://www.perlmonks.org?node_id=933658

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

I'll admit my grasp on IO layers is fuzzy at best. However, I'm trying to read some CSV files using :crlf. I could just double chomp the lines when needed, or set $/ = "\r\n" (which I worry might have unintended consequences), but I'd much rather figure out how to do this with layers, as I think it will help in the long run. Anyway, my problem is that when reading files using the diamond operator, :crlf seems to work fine, but when opening named files later in the program, it is not working. Like so:

use strict; use warnings; use open IN => ':crlf'; while (<>) { die ("Carriage return in $ARGV") if (/\r/); } open (INPUT, "myfile.csv") or die ("Can't open myfile.csv"); while (<INPUT>) { die ("Carriage return in myfile.csv") if (/\r/); }

All the files entered on the command line are CSV files that have CRLF line endings, as does "myfile.csv". But it makes it through the first while loop and dies at the 2nd on line 1 of "myfile.csv". I tried making it open (INPUT, "<:crlf", "myfile.csv") just in case it was somehow losing the original use flag, and it made no difference.

Replies are listed 'Best First'.
Re: crlf layer working on diamond operator, but not filehandle reads
by ikegami (Patriarch) on Oct 25, 2011 at 17:37 UTC

    Should work.

    Does work with 5.10.1 and 5.12.1:

    $ perl -e'print "foo,bar,baz\r\n";' > myfile.csv $ perl -e' use strict; use warnings; use open IN => ":crlf"; while (<>) { die ("Carriage return in $ARGV") if (/\r/); } open (INPUT, "myfile.csv") or die ("Can'\''t open myfile.csv"); while (<INPUT>) { die("Carriage return in myfile.csv") if (/\r/); } print "ok\n"; ' myfile.csv ok

    Are you sure there are no CR other than right before a LF?

    if (/\r/) { require Data::Dumper; local $Data::Dumper::Useqq = 1; local $Data::Dumper::Terse = 1; local $Data::Dumper::Indent = 0; die ("Carriage return in myfile.csv " . Data::Dumper::Dumper( +$_)); }

      I know I let this thread die, but honestly I never figured out what was going on. Running the exact same code using perl -e and perl myprog.pl produced different results, and I never determined what was causing it.

      However, I figured I should probably say what I ended up doing in case someone ever reads this with a similar problem. Setting :crlf as the current layer by use open IN => ":crlf" only seemed to work for files read by the empty diamond operator, and somehow broke for explicitly opened files, so I simply turned it off after the while(<>) loop with a no open IN => ":crlf", and explicitly added the layer to each file I opened (e.g. open(INFILE, "<:crlf", "myfile.csv")). This seems to always work, but only when the global layer isn't used.

        only seemed to work for files read by the empty diamond operator

        I proved otherwise.