in reply to Problems with changing $/ and Tie::File in RO mode

As an alternative to your approach, you might want to look into PerlIO, in particular the :crlf layer, which is responsible for Perl's different handling of newlines on Windows vs. Unix:

:crlf
A layer that implements DOS/Windows like CRLF line endings. On read converts pairs of CR,LF to a single "\n" newline character. On write converts each "\n" to a CR,LF pair. (...)

By default, that layer is active on Windows perls, but nothing is keeping you from using the layer on Unix to read Windows-style text files, or removing the layer on Windows to write Unix-style files.

Replies are listed 'Best First'.
Re^2: Problems with changing $/ and Tie::File in RO mode (:crlf)
by Ooops (Initiate) on Oct 01, 2009 at 16:30 UTC

    Hi almut,
    you are right, this is interesting and I'm going to study on that, but does it also work with the 'Tie::File' to an @array? (If so, what do I have to code?)
    The advantage of 'Tie'ing in my way is to use zero memory, because I do not read the file into RAM.

      does it also work with the 'Tie::File' to an @array?

      Yes.  For example, to read Windows-style files on Unix:

      #!/usr/bin/perl use Tie::File; my $fname = shift @ARGV; open my $fh_crlf, "<:crlf", $fname or die "Couldn't open '$fname': $!" +; tie my @array, 'Tie::File', $fh_crlf, mode => O_RDONLY, memory => 0 or + die $!; for my $line (@array) { # ... # $line has no trailing \r }

        Hi almut,
        I'm sorry, this excursion was very interisting, but that *may* work from the unix side, but on my both XP systems (v5.8.8 and v5.10.0 with komodo) it doesn't work; the yield is only *one* array element.
        BUT I have to apologize! The solution is written in the 'ActivePerl User Guide -- Tie::File', witch I did read some times before.
        There is another parameter called 'recsep' that worked very well for me. So here is the code.

        use Tie::File; # Record separator per default = $/ use Fcntl 'O_RDONLY'; # open in read-only mode my ($sep1, $sep2) = ($ENV{'windir'}) # determine OS ? ("\r\n", "\n") : ("\n", "\r\n"); my $file = shift @ARGV; tie my @array, 'Tie::File', $file, mode => O_RDONLY, memory => 0, recsep => $sep1 or die $!; my $n_recs = @array; # how many records are in the file? unless ($n_recs > 1) { untie @array; tie @array, 'Tie::File', $file, mode => O_RDONLY, memory => 0, recsep => $sep2 or die $!; $n_recs = @array; print join ("~SEP~", @array); die "Found only one array element\n" unless $n_recs > 1; }

        Voila! Proggy dies not (in XP).
        Nevertheless thanx for your help, almut.
        ... And I'm still wondering, why neither changing of $/ nor the setting of "<:unix" had any effect at all.