I mentioned this on IRC today with little response.
I was pretty surprised by the way readline behaves for
non-blocking file handles. All I'd like to know is if this
behaviour is by design (and documented somewhere) or if
it's rather a bug.
Here's the code:
use feature ':5.10';
use IO::File;
use IO::Select;
my $prog = qq/ $^X -e '$|++; while (1) { print
"x"; sleep 2 }' /;
my $fh = IO::File->new("$prog |") or die
"$prog: $!n";
$fh->blocking(0);
my $io = IO::Select->new([$fh]);
while (1) {
if ($io->can_read(1)) {
my $read = <$fh> // 'undef';
say "$. = $. : read '$read'";
}
else { say "nope..." }
}
__END__
mhx r2d2 ~ $ bleadperl test.pl
$. = 1 : read 'x'
nope...
nope...
$. = 2 : read 'x'
nope...
nope...
$. = 3 : read 'x'
nope...
$. = 4 : read 'x'
nope...
I would have expected readline to return 'undef' for as
long
as it doesn't see $/ in the input stream. (In the above
case,
that would be forever.) After all, this is called
read*line*,
but it's only returning characters.
Even more strange is the behaviour of $., which simply
increments
with each character that is read (or, to be exact, with
each
successful call readline).
Looking at the code, all this makes perfect sense.
sv_gets()
calls PerlIO_getc() until $/ or EOF is found. In case of a
non-blocking file handle, PerlIO_getc() returns EOF if it
can't read a byte. Thus sv_gets() assumes the last line has
been read, and do_readline() happily increments $..
Marcus
--
If I'd known computer science was going to be like this, I'd
never have
given up being a rock 'n' roll star.
-- G. Hirst
|