Class: Namelab::ListRef

Inherits:
Object
  • Object
show all
Defined in:
lib/namelab/list_ref.rb

Constant Summary collapse

NORMALIZED_FMT =
"%1$*2$s"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io_proc) ⇒ ListRef

Returns a new instance of ListRef.



9
10
11
12
# File 'lib/namelab/list_ref.rb', line 9

def initialize(io_proc)
  @proc = io_proc
  sync!
end

Instance Attribute Details

#lines_countObject (readonly)

Returns the value of attribute lines_count.



7
8
9
# File 'lib/namelab/list_ref.rb', line 7

def lines_count
  @lines_count
end

#procObject (readonly)

Returns the value of attribute proc.



7
8
9
# File 'lib/namelab/list_ref.rb', line 7

def proc
  @proc
end

Instance Method Details

#closeObject



36
37
38
39
40
41
42
43
# 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) ⇒ Object



20
21
22
23
# 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(&block) ⇒ Object

:yields:



53
54
55
56
# File 'lib/namelab/list_ref.rb', line 53

def filter(&block) # :yields:
  @filter = block.to_proc
  self
end

#filtered_sampleObject

:yields:



68
69
70
71
72
73
74
75
76
# 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) ⇒ Object



78
79
80
81
82
83
84
85
86
# 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

#ioObject



25
26
27
# File 'lib/namelab/list_ref.rb', line 25

def io
  @io ||= @proc[]
end

#lines(enum: true, &block) ⇒ Object



14
15
16
17
18
# File 'lib/namelab/list_ref.rb', line 14

def lines(enum: true, &block)
  enum ? each_line(&block) : block.(each_line)
ensure
  rewind
end

#rewindObject



45
46
47
# File 'lib/namelab/list_ref.rb', line 45

def rewind
  @io&.rewind
end

#sample(filter = true) ⇒ Object



58
59
60
61
62
63
64
65
66
# 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_linenoObject



49
50
51
# File 'lib/namelab/list_ref.rb', line 49

def sample_lineno
  rand(lines_count)
end

#sync!Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# 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_ioObject



29
30
31
32
33
34
# File 'lib/namelab/list_ref.rb', line 29

def with_io
  io
  yield(self)
ensure
  close
end