in reply to PerlIO::via FILL subroutine question

thor,
I am not sure where you are running into the newline problem. I am betting it is with <>/readline. That is because they define a record by looking at $/ (see perldoc perlvar). PerlIO::via allows you to define your own buffering methods, but readline is still going to return records from the buffer by looking at $/. I don't think you are going to be able to use PerlIO::via to change that behavior. Notice the comment:
package rdw; use strict; use warnings; sub PUSHED { bless \*PUSHED,$_[0] } sub FILL { my ($length, $record); read $_[1], $length, 1; return undef if eof $_[1]; read $_[1], $record, $length; # uncomment next line to see it is actually working # print "$record\n"; return $record; } sub WRITE { return undef } package main; open( my $in, '<:via(rdw)', 'foo.txt' ) or die $!; while ( <$in> ) { print "$_\n"; } __END__ # foo.txt - output is aababc 1a2ab3abc
If I guessed correctly, there are other ways to do it - speak up.

Cheers - L~R

Replies are listed 'Best First'.
Re^2: PerlIO::via FILL subroutine question
by thor (Priest) on Oct 04, 2004 at 22:31 UTC
    Yeah, that's the gist of it (the rdw's are packed shorts, but that's a detail that doesn't matter). So, is there some way to implement readline so that I can provide perl with what my notion of a line is? At first, that's what I thought that FILL did, but I guess I was mistaken...

    thor

    Feel the white light, the light within
    Be your own disciple, fan the sparks of will
    For all of us waiting, your kingdom will come

      thor,
      You can look at subclassing IO::File, but that is going to end up giving you a different OO interface. The other option is to tie the filehandle. I was disappointed that Tie::FileHandle::Base didn't do more in the way of giving you default methods to inherit. Here is a very rough proof of concept.
      package rdw; use Carp; sub TIEHANDLE { my ($class, $file) = @_; open ( my $file , '<', $file ) or croak "Unable to open $file : $! +"; return bless \$file , $class; } sub READLINE { my $self = shift; my ($length, $record); read $$self, $length, 1; return undef if eof $$self; read $$self, $record, $length; return $record; } 42; # and a script that uses it #!/usr/bin/perl use strict; use warnings; use rdw; tie *fh, 'rdw', 'foo.rdw' or die "Unable to tie : $!"; while ( <fh> ) { print "$_\n"; } __END__ # foo.rdw - outputs "a\nab\nabc\nabcd\n" as desired 1a2ab3abc4abcd
      See perldoc perltie for more information

      Cheers - L~R