class Namelab::ListRef

Constants

NORMALIZED_FMT

Attributes

lines_count[R]
proc[R]

Public Class Methods

new(io_proc) click to toggle source
# File lib/namelab/list_ref.rb, line 9
def initialize(io_proc)
  @proc = io_proc
  sync!
end

Public Instance Methods

close() click to toggle source
# File lib/namelab/list_ref.rb, line 36
def close
  @io&.close
  if defined?(@_tmp)
    File.unlink(@_tmp)
    remove_instance_variable(:@_tmp)
  end
  remove_instance_variable(:@io)
end
each_line(&block) click to toggle source
# File lib/namelab/list_ref.rb, line 20
def each_line(&block)
  return to_enum(:each_line) unless block_given?
  io.each_line(chomp: true, &block)
end
filter() { || ... } click to toggle source
# File lib/namelab/list_ref.rb, line 53
def filter(&block) # :yields:
  @filter = block.to_proc
  self
end
filtered_sample() { || ... } click to toggle source
# File lib/namelab/list_ref.rb, line 68
def filtered_sample # :yields:
  result = nil
  while result.nil?
    value = sample(false)
    redo unless yield(value)
    result = value
  end
  result
end
get(lineno) click to toggle source
# File lib/namelab/list_ref.rb, line 78
def get(lineno)
  offset = lineno * @sample_size
  begin
    @io.pread(@sample_size, offset)
  rescue EOFError
    offset -= @sample_size
    retry
  end
end
io() click to toggle source
# File lib/namelab/list_ref.rb, line 25
def io
  @io ||= @proc[]
end
lines(enum: true, &block) click to toggle source
# File lib/namelab/list_ref.rb, line 14
def lines(enum: true, &block)
  enum ? each_line(&block) : block.(each_line)
ensure
  rewind
end
rewind() click to toggle source
# File lib/namelab/list_ref.rb, line 45
def rewind
  @io&.rewind
end
sample(filter = true) click to toggle source
# File lib/namelab/list_ref.rb, line 58
def sample(filter = true)
  if filter && defined?(@filter)
    proc = @filter
    remove_instance_variable(:@filter)
    filtered_sample(&proc)
  else
    get(sample_lineno).strip
  end
end
sample_lineno() click to toggle source
# File lib/namelab/list_ref.rb, line 49
def sample_lineno
  rand(lines_count)
end
sync!() click to toggle source
# File lib/namelab/list_ref.rb, line 90
def sync!
  remove_instance_variable(:@_tmp) if defined?(@_tmp)
  tempfile = Tempfile.new(File.basename(io.path))
  lines enum: false do |enum|
    @sample_size = enum.max_by(&:length).length
    rewind
    lines_count = 0
    enum.each do |v|
      tempfile.printf(NORMALIZED_FMT, v, -@sample_size)
      lines_count += 1
    end
    @lines_count = lines_count
  end
  tempfile.rewind
  close
  @_tmp = tempfile.path
  @io = tempfile.to_io
  at_exit { close }
end
with_io() { |self| ... } click to toggle source
# File lib/namelab/list_ref.rb, line 29
def with_io
  io
  yield(self)
ensure
  close
end