B
Brian Marick
I'm writing a book on Ruby for testers. The first example is writing a
souped-up "tail -f" program that'll be useful for exploratory testing.
Here's the very first implementation:
open_file = File.open('the-log')
loop do
puts open_file.readlines
sleep 1
end
This works on Windows (Win2K, Ruby 1.8.1). If another program is
writing steadily to 'the-log', this program steadily prints out new
lines.
It does not work on OS X (and, I'm guessing, other versions of Unix).
Once readlines hits the end of file, it never returns anything but [].
I believe this happens because readlines() eventually ends up in
io.c/appendline and calls getc(3). Because feof(3), once set, is sticky
until clearerr(3) is called, any additions to the file are ignored.
(sysread, which ends up calling read(2), avoids this consequence of
stdio behavior.)
There's a workaround: do something that calls clearerr(3) by side
effect. This is the first one I found, though there may be more:
open_file.pos = open_file.pos
I don't want to have to explain that to a tester just learning
programming. I can hide this inside a required file that overrides
File#readlines, but it's still kludgy and some set of readers will
discover the kludge quickly.
It doesn't seem like the behavior should be inconsistent on Unix and
Windows - you can't write a portable program that depends on either
behavior. Of the two behaviors, the Windows one seems better to me: it
lets you do more things more easily.
An alternative would be to have an IO#clear_eof message. Because of the
#ifdefness of io.c, that's a safer route.
RCR?
souped-up "tail -f" program that'll be useful for exploratory testing.
Here's the very first implementation:
open_file = File.open('the-log')
loop do
puts open_file.readlines
sleep 1
end
This works on Windows (Win2K, Ruby 1.8.1). If another program is
writing steadily to 'the-log', this program steadily prints out new
lines.
It does not work on OS X (and, I'm guessing, other versions of Unix).
Once readlines hits the end of file, it never returns anything but [].
I believe this happens because readlines() eventually ends up in
io.c/appendline and calls getc(3). Because feof(3), once set, is sticky
until clearerr(3) is called, any additions to the file are ignored.
(sysread, which ends up calling read(2), avoids this consequence of
stdio behavior.)
There's a workaround: do something that calls clearerr(3) by side
effect. This is the first one I found, though there may be more:
open_file.pos = open_file.pos
I don't want to have to explain that to a tester just learning
programming. I can hide this inside a required file that overrides
File#readlines, but it's still kludgy and some set of readers will
discover the kludge quickly.
It doesn't seem like the behavior should be inconsistent on Unix and
Windows - you can't write a portable program that depends on either
behavior. Of the two behaviors, the Windows one seems better to me: it
lets you do more things more easily.
An alternative would be to have an IO#clear_eof message. Because of the
#ifdefness of io.c, that's a safer route.
RCR?