tailコマンドをRubyで

tail -F だけやな

#!/usr/bin/env ruby

class Tail
  def initialize tailed_file, &blk
    check_file_validity(tailed_file)
    @tailed_file = tailed_file
    if block_given?
      @callback = blk
    else
     @callback = lambda {|s| STDOUT.write s }
    end
  end

  def follow s=1
    open(@tailed_file, 'r') do |f|
      f.seek(0, 2)
      while true
        curr_position = f.tell
        line = f.gets
        if line
          @callback.call(line)
        else
          f.seek(curr_position)
        end
        sleep s
      end
    end
  end

  def register_callback &blk
    @callback = blk
    self
  end

  private

  def check_file_validity file
    unless File.exists? file
      raise TailError, "File #{file} does not exist"
    end

    unless File.readable? file
      raise TailError, "File #{file} not readable"
    end

    unless File.ftype(file) != "directory"
      raise TailError, "File #{file} is a directory"
    end
  end
end

class TailError < Exception; end


if __FILE__ == $0
  t = Tail.new('/var/log/syslog').register_callback do |txt|
    puts txt
  end

  t.follow(5)
end