...that the AnyCRLF module is automatically putting the crlf-layer on the stack if it is not already available.
Good question. Like you, I couldn't figure out a way
to get at the file handle of the lower layer in either OPEN or
PUSHED. OTOH, as you do have access to the handle in the FILL
method, you could use binmode to compose the following hack:
package PerlIO::via::AnyCRLF;
sub PUSHED {
my ($class) = @_;
my $have_crlf;
return bless \$have_crlf, $class;
}
sub FILL {
my ($self, $fh) = @_;
binmode $fh, ":crlf" unless $$self;
$$self = 1;
my $len = read $fh, my $buf, 4096;
if (defined $buf) {
$buf =~ s/\r/\n/g;
}
return $len > 0 ? $buf : undef;
}
1;
Although this works, it doesn't feel right. For one, it violates
the principle of least surprise... as you can see with the debug
prints before and after reading from the file handle.
#!/usr/bin/perl
use PerlIO::via::AnyCRLF;
open my $f, "<:via(AnyCRLF)", "le.txt" or die $!;
# debug
# print "layers before reading :", join(':',PerlIO::get_layers($f)), "
+\n"; # :unix:perlio:via
print while <$f>;
# print "layers after reading :", join(':',PerlIO::get_layers($f)), "
+\n"; # :unix:perlio:crlf:via
The other (similarly suboptimal) way would be to take care of
opening a handle yourself:
package PerlIO::via::AnyCRLF;
sub PUSHED {
my ($class) = @_;
my $fh_ref;
return bless \$fh_ref, $class;
}
sub FILL {
my ($self) = @_;
my $len = read $$self, my $buf, 4096;
if (defined $buf) {
$buf =~ s/\r/\n/g;
}
return $len > 0 ? $buf : undef;
}
sub OPEN {
my ($self, $path) = @_;
open $$self, "<:crlf", $path or die $!;
# debug
# print "AnyCRLF layers :", join(':',PerlIO::get_layers($$self)),
+"\n";
return 1;
}
1;
but in this case, the layer can no longer be properly stacked, as
it always becomes the bottommost layer. (Might not be a problem in your
particular case, though.)
Unfortunately, the PerlIO::via docs leave a number of questions
unanswered (e.g. what is OPEN supposed to return; why does it fail to
pass a handle, even if there is in fact a lower layer? etc.), and code
samples using OPEN are hard
to find.
Well, maybe the "is subject to change" note for the *OPEN methods is
meant seriously — and noone has yet worked out in what way they
should be changed :)
|