in reply to Re: Can't get Tie::File working
in thread Can't get Tie::File working

$#content will return index of the last element in the array

OK, this explains the second half of the problem. But why do I get "the whole file" slurped into $content[0]? I had expected that each line in the file is one line in the array.

Could it have to do with line endings? The file is a Unix-Style file (\n separated), but the program is running on Windows (ActiveState Perl). But OTOH, the usual operations to read files (open() etc.) don't seem to have a problem with the different line endings...

-- 
Ronald Fischer <ynnor@mm.st>

Replies are listed 'Best First'.
Re^3: Can't get Tie::File working
by Corion (Patriarch) on Oct 14, 2008 at 11:45 UTC

    See the Tie::File documentation on recsep:

    By default, the meaning is the same as for the <...> operator: It's a string terminated by $/, which is probably "\n". (Minor exception: on DOS and Win32 systems, a 'record' is a string terminated by "\r\n".)

    So that's exactly your problem. Change recsep to \n and likely everything will "just work".

      Change recsep to \n

      I hope this won't be necessary, because I don't know in advance which line ending style the file will have. There is, however, something I don't quite understand: As you correctly say, the documentation explains By default, the meaning is the same as for the <...> operator. But now look at the following program, which uses the angle operator insead of tie, to read the same file:

      use strict; use warnings; sub printfirst { my $f=shift; open(F,$f) or die "$!"; my $firstline=<F>; print "$f: $firstline\n"; } printfirst('ALSF.pm');
      In this case, $firstline correctly gets only the first line in the file, although the lines in the file are terminated by \n and we are running on Windows. Shouldn't then $firstline also contain the whole file in this case?

      -- 
      Ronald Fischer <ynnor@mm.st>

        I guess that's some inexactness in the documentation of Tie::File. Looking at the source code, there is the following code, which sets/forces $/ to \r\n:

        sub _default_recsep { my $recsep = $/; if ($^O eq 'MSWin32') { # Dos too? # Windows users expect files to be terminated with \r\n # But $/ is set to \n instead # Note that this also transforms \n\n into \r\n\r\n. # That is a feature. $recsep =~ s/\n/\r\n/g; } $recsep; }

        So, you'll have to read the first few bytes (or up to the first \n), guess the line ending from that, and then use the recsep option to force the line ending.