Class: TrickBag::Enumerables::FileLineReader

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/trick_bag/enumerables/file_line_reader.rb

Overview

Reads a file containing strings, one on each line, and feeds them in its each() method. Strips all lines leading and trailing whitespace, and ignores all empty lines and lines beginning with the comment character ‘#’.

If calling each without a block to get an enumerator, call enumerator.close when done if not all values have been exhausted, so that the input file will be closed.

Supports specifying a starting position and maximum count. For example if the starting position is 2, then the first 2 valid lines will be discarded, and yielding will begin with the next valid line.

Similarly, specifying a maximum count will cause yielding to end after max_count objects have been yielded.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filespec, start_pos = :first, max_count = :infinite) ⇒ FileLineReader

Returns a new instance of FileLineReader.

Parameters:

  • filespec
    • the file from which to read lines; blank/empty lines and lines

    with the first nonblank character == ‘#’ will be ignored.

  • start_pos (defaults to: :first)
    • the record number, zero offset, at which to begin each() processing

  • max_count (defaults to: :infinite)
    • the maximum number of records to be served by each()



29
30
31
32
# File 'lib/trick_bag/enumerables/file_line_reader.rb', line 29

def initialize(filespec, start_pos = :first, max_count = :infinite)
  @filespec = filespec
  @start_and_max = TrickBag::Numeric::StartAndMax.new(start_pos, max_count)
end

Instance Attribute Details

#filespecObject (readonly)

Returns the value of attribute filespec.



23
24
25
# File 'lib/trick_bag/enumerables/file_line_reader.rb', line 23

def filespec
  @filespec
end

#start_and_maxObject (readonly)

Returns the value of attribute start_and_max.



23
24
25
# File 'lib/trick_bag/enumerables/file_line_reader.rb', line 23

def start_and_max
  @start_and_max
end

Instance Method Details

#close_file(file) ⇒ Object

Closes the file if it is not null and has not already been closed



55
56
57
58
59
# File 'lib/trick_bag/enumerables/file_line_reader.rb', line 55

def close_file(file)
  if file && (! file.closed?)
    file.close
  end
end

#eachObject

Returns an Enumerator if called without a block; in that case, remember to close the file explicitly by calling the enumerator’s close method if you finish using it before all values have been exhausted.



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/trick_bag/enumerables/file_line_reader.rb', line 85

def each

  file = File.open(filespec, 'r')
  return to_enum(file) unless block_given?

  valid_record_num = 0
  yield_count = 0

  begin

    file.each do |line|
      line.strip!
      if line_valid?(line)
        if start_and_max.start_position_reached?(valid_record_num)
          yield(line)
          yield_count += 1
          if start_and_max.max_count_reached?(yield_count)
            return
          end
        end

        valid_record_num += 1
      end
    end

  ensure
    close_file(file)
  end
end

#line_valid?(line) ⇒ Boolean

Returns whether or not this line is valid (eligible for yielding), specifically not empty and not a comment.

Parameters:

  • line

    the line to test

Returns:

  • (Boolean)

    whether or not this line is valid (eligible for yielding), specifically not empty and not a comment



49
50
51
# File 'lib/trick_bag/enumerables/file_line_reader.rb', line 49

def line_valid?(line)
  ! (line.empty? || /^#/ === line)
end

#max_countObject

Returns the maximum number of objects to be yielded.

Returns:

  • the maximum number of objects to be yielded



41
42
43
# File 'lib/trick_bag/enumerables/file_line_reader.rb', line 41

def max_count
  start_and_max.max_count
end

#start_posObject

Returns the position of the first valid object to be yielded.

Returns:

  • the position of the first valid object to be yielded.



35
36
37
# File 'lib/trick_bag/enumerables/file_line_reader.rb', line 35

def start_pos
  start_and_max.start_pos
end

#to_enum(file) ⇒ Object

Any enumerator returned should have a close method to close the file from which lines are read. This method gets an enumerator from the superclass, and adds a ‘file’ attribute and a close method to it.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/trick_bag/enumerables/file_line_reader.rb', line 65

def to_enum(file)
  enumerator = super()
  enumerator.instance_variable_set(:@file, file)

  # This method is defined on the instance of the new enumerator.
  # It closes the input file.
  def enumerator.close
    if @file && (! @file.closed?)
      @file.close
      @file = nil
    end
  end

  enumerator
end

#to_sObject



116
117
118
# File 'lib/trick_bag/enumerables/file_line_reader.rb', line 116

def to_s
  "#{self.class}: filespec: #{filespec}, start_pos: #{start_pos.inspect}, max_count: #{max_count.inspect}"
end