A very basic tail -f implementation

From: Paul Brannan [mailto:pbrannan@atdesk.com]

I have an implementation of tail -f that looks similar, except it
doesn’t seek to the end of file at start

I guess to truly imitate the *nix tail -f command, it should read the 10
last lines and then start its wait cycle. Should it be that faithful?

, and it’s called like this:

File.open(filename) do |input|
tail_f(input) do |line|
puts line
end
end

Two advantages here:

  1. If an exception is raised from inside the block, the file will be
    properly closed.
  2. I get my input line-by-line, which imo is much more useful than
    buffersize-by-buffersize.

Regarding the file closure, I think I was relying on scope to kill it. I
wasn’t really sure how egregious it was to not politely close a file. In
Perl, it’s recommended but not required.

As for the input method, I think I like your line by line approach better.
I used the buffersize approach because, well, that’s how the Perl module did
it. :slight_smile:

Some advantages of your implementation:

  1. It is an object, and acts somewhat like an IO object, thus
  2. If RCR#65 (http://www.rubygarden.org/article.php?sid=179) were
    accepted, it could easily be modified to inherit from IO and make
    this class act just like a pipe.

I read the RCR. I think it’s a good idea, though it also sounds like quite
a bit of work. Any idea on the status of this? Sounds like a good topic
for a Ruby gathering. :slight_smile:

  1. The sleep interval and buffer size are adjustable.

My implementation:

def clearerr(io)
offset = io.tell
io.seek(offset)
end

def tail_f(input)
loop do
line = input.gets
yield line if not line.nil?
if input.eof? then
sleep 1
clearerr(input)
end
end
end

Nice. I’m gonna work on this some today, so I’ll see if perhaps I
can/should use this approach instead.

Regards,

Dan

···

-----Original Message-----