Class: CSVH::Reader

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/csvh/reader.rb

Overview

Sequantially and lazily reads from CSV-formatted data that has a header row. Allows accessing headers before reading any subsequent data rows and/or when no additional data rows are present in the data.

Constant Summary collapse

DEFAULT_CSV_OPTS =
{
  headers: :first_row,
  return_headers: true
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(csv) ⇒ Reader

Returns a new reader based on the given CSV object. The CSV object must be configured to return a header row (a CSV::ROW that returns true from its #header? method as its first item. The header item must also not have been read yet.

Parameters:

  • csv (CSV)

    A Ruby ::CSV object.



84
85
86
87
88
89
90
91
92
93
# File 'lib/csvh/reader.rb', line 84

def initialize(csv)
  unless csv.return_headers?
    raise \
      InappropreateCsvInstanceError,
       "%{self.class} requires a CSV instance that returns headers." \
      " It needs to have been initialized with non-false/nil values" \
      " for :headers and :return_headers options."
  end
  @csv = csv
end

Class Method Details

.from_file(file_path, **opts) {|the| ... } ⇒ Reader, object Also known as: foreach

When called without a block argument, returns an open reader for data from the file at the given file_path.

When called with a block argument, passes an open reader for data from the file to the given block, closes the reader (and its underlying file IO channel) before returning, and then returns the value that was returned by the block.

By default, the underlying CSV object is initialized with default options for data with a header row and to return the header row. Any oadditional options you supply will be added to those defaults or override them.

Parameters:

  • file_path (String)

    the path of the file to read.

  • opts

    options for CSV.new.

Yield Parameters:

  • the (Reader)

    new reader.

Returns:

  • (Reader, object)

    the new reader or the value returned from the given block.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/csvh/reader.rb', line 39

def from_file(file_path, **opts)
  opts = default_csv_opts.merge(opts)
  io = File.open(file_path, 'r')
  csv = CSV.new(io, **opts)
  instance = new(csv)

  if block_given?
    begin
      yield instance
    ensure
      instance.close unless instance.closed?
    end
  else
    instance
  end
end

.from_string_or_io(data, **opts) ⇒ Reader Also known as: parse

Returns an open reader for data from given string or readable IO stream.

Parameters:

  • data (String, IO)

    the source of the data to read.

  • opts

    options for CSV.new.

Returns:

  • (Reader)

    the new reader.



62
63
64
65
66
# File 'lib/csvh/reader.rb', line 62

def from_string_or_io(data, **opts)
  opts = default_csv_opts.merge(opts)
  csv = CSV.new(data, **opts)
  new(csv)
end

Instance Method Details

#each {|| ... } ⇒ Object

When given a block, yields each data row of the data source in turn as CSV::Row instances. When called without a block, returns an Enumerator over those rows.

Does not yield the header row, however, the headers are available via the #headers method of the reader or the row.

Yield Parameters:

  • (CSV::Row)


135
136
137
138
139
140
141
142
# File 'lib/csvh/reader.rb', line 135

def each
  headers
  if block_given?
    @csv.each { |row| yield row }
  else
    @csv.each
  end
end

#headersArray<String>

Returns the list of column header values from the CSV data.

If any rows have already been read, then the result is immediately returned, having been recorded when the header row was initially encountered.

If no rows have been read yet, then the first row is read from the data in order to return the result.

Returns:

  • (Array<String>)

    the column header names.



110
111
112
113
114
115
116
117
118
119
120
# File 'lib/csvh/reader.rb', line 110

def headers
  @headers ||= begin
    row = @csv.readline
    unless row.header_row?
      raise \
        CsvPrematurelyShiftedError,
        "the header row was prematurely read from the underlying CSV object."
    end
    row.headers
  end
end

#to_csvh_readerReader

Returns the target of the method call.

Returns:

  • (Reader)

    the target of the method call.



96
97
98
# File 'lib/csvh/reader.rb', line 96

def to_csvh_reader
  self
end