Class: Bashcov::FieldStream

Inherits:
Object
  • Object
show all
Defined in:
lib/bashcov/field_stream.rb

Overview

Classes for streaming token-delimited fields

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(read = nil) ⇒ FieldStream

Returns a new instance of FieldStream.

Parameters:

  • read (IO) (defaults to: nil)

    an IO object opened for reading



9
10
11
# File 'lib/bashcov/field_stream.rb', line 9

def initialize(read = nil)
  @read = read
end

Instance Attribute Details

#readObject

Returns the value of attribute read.



6
7
8
# File 'lib/bashcov/field_stream.rb', line 6

def read
  @read
end

Instance Method Details

#each(delimiter, field_count, start_match) {|field| ... } ⇒ Object

Yields fields extracted from a input stream

Parameters:

  • delimiter (String, nil)

    the field separator

  • field_count (Integer)

    the number of fields to extract

  • start_match (Regexp)

    a Regexp that, when matched against the input stream, signifies the beginning of the next series of fields to yield

Yield Parameters:

  • field (String)

    each field extracted from the stream. If start_match is matched with fewer than field_count fields yielded since the last match, yields empty strings until field_count is reached.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/bashcov/field_stream.rb', line 36

def each(delimiter, field_count, start_match)
  return enum_for(__method__, delimiter, field_count, start_match) unless block_given?

  # Whether the current field is the start-of-fields match
  matched_start = nil

  # The number of fields processed since passing the last start-of-fields
  # match
  seen_fields = 0

  fields = each_field(delimiter)

  # Close over +field_count+ and +seen_fields+ to yield empty strings to
  # the caller when we've already hit the next start-of-fields match
  yield_remaining = -> { (field_count - seen_fields).times { yield "" } }

  # Advance until the first start-of-fields match
  loop { break if fields.next =~ start_match }

  fields.each do |field|
    # If the current field is the start-of-fields match...
    if field =~ start_match
      # Fill out any remaining (unparseable) fields with empty strings
      yield_remaining.call

      matched_start = nil
      seen_fields = 0
    elsif seen_fields < field_count
      yield field
      seen_fields += 1
    end
  end

  # One last filling-out of empty fields if we're at the end of the stream
  yield_remaining.call

  read.close unless read.closed?
end

#each_field(delimiter) {|field| ... } ⇒ void

This method returns an undefined value.

A convenience wrapper around each_line(delimiter) that also does chomp(delimiter) on the yielded line.

Parameters:

  • delimiter (String, nil)

    the field separator for the stream

Yield Parameters:

  • field (String)

    each chomped line



18
19
20
21
22
23
24
# File 'lib/bashcov/field_stream.rb', line 18

def each_field(delimiter)
  return enum_for(__method__, delimiter) unless block_given?

  read.each_line(delimiter) do |line|
    yield line.chomp(delimiter).encode("utf-8", invalid: :replace)
  end
end