class CSV::AutoParser

Constants

VERSION

Attributes

file_path[R]
header_line_number[R]
pre_header_rows[R]

Public Class Methods

convert_header_to_method_name(header) click to toggle source

This is the method called by AutoParser to turn header names into legal method names. Redefine as necessary.

# File lib/csv/autoparser.rb, line 24
def self.convert_header_to_method_name header
  header.to_s.downcase.strip.gsub(/\s+/, '_').gsub(/-+/, '_').gsub(/[^\w]/, '').to_sym
end
new(data, opts={}) click to toggle source

data can be path of CSV file in addition to a CSV String or an IO object like CSV.new. All CSV.new options are supported via opts. If an +&is_header+ block is provided, it takes precedence over the CSV.new :headers option. A :optional_headers option has been added for specifying headers that may not be present in the CSV, but you do not want a NoMethodError to raise when accessing a field using the header method style accessor.

Calls superclass method
# File lib/csv/autoparser.rb, line 48
def initialize data, opts={}, &is_header
  @header_line_number = nil
  @pre_header_rows = []
  @optional_headers = [opts.delete(:optional_headers)].flatten.compact
  @data_io = if data.is_a?(IO) or data.is_a?(StringIO)
               data
             elsif data.is_a?(String)
               if File.exists?(data)
                 File.open(@file_path = File.expand_path(data), binmode: true) 
               else
                 StringIO.new(data)
               end
             else
               raise ArgumentError, "data must be a path to a CSV file, a CSV formatted String, or an IO object."
             end
  if block_given?
    header_pos = @data_io.pos
    csv_line_number = 0
    header_finder = CSV.new(@data_io, opts.merge(:headers => false)).each do |row| 
      csv_line_number += 1
      if is_header.call(csv_line_number, row)
        @header_line_number = csv_line_number
        break
      else
        @pre_header_rows << CSV::AutoParser::PreHeaderRow.create(row, @file_path, csv_line_number)
      end
      header_pos = @data_io.pos
    end
    raise HeaderRowNotFound, "Could not find header row#{@file_path ? " in #{@file_path}" : "" }." if @header_line_number.nil?
    @data_io.seek header_pos
    @data_io = StringIO.new(@data_io.read)
    super(@data_io, opts.merge(:headers => true))
  else
    @header_line_number = 1 if opts[:headers] == :first_row or opts[:headers] == true
    super(@data_io, opts)
  end
end

Public Instance Methods

orig_shift()
Alias for: shift
shift() click to toggle source

Overriden to add methods for optional headers which were not present in the CSV. Also, sets a rows @file_path and @line_number.

# File lib/csv/autoparser.rb, line 90
def shift
  row = orig_shift
  if row and row.is_a?(Row) and row.line_number.nil? # sometimes nil. sometimes not a row. sometimes row is repeated.
    row.instance_variable_set(:@line_number, @data_io.lineno + (@header_line_number || 1) - 1) #if @data_io
  end
  [@optional_headers].flatten.compact.each do |h|
    method_name = self.class.convert_header_to_method_name(h)
    unless row.respond_to? method_name
      row.define_singleton_method(method_name) {nil}
    end
  end
  return row
end
Also aliased as: orig_shift