class Stockboy::Readers::FixedWidth

For reading fixed-width data split by column widths

Public Class Methods

new(opts={}, &block) click to toggle source

Initialize a new fixed-width reader

@param [Hash] opts @option opts [Array<Integer>, Hash<Integer>] headers @option opts [Integer] skip_header_rows @option opts [Integer] skip_footer_rows @option opts [String] encoding

Calls superclass method Stockboy::Reader::new
# File lib/stockboy/readers/fixed_width.rb, line 74
def initialize(opts={}, &block)
  super
  @headers          = opts[:headers]
  @skip_header_rows = opts.fetch(:skip_header_rows, 0)
  @skip_footer_rows = opts.fetch(:skip_footer_rows, 0)
  DSL.new(self).instance_eval(&block) if block_given?
end

Public Instance Methods

parse(data) click to toggle source
# File lib/stockboy/readers/fixed_width.rb, line 82
def parse(data)
  validate_headers
  data.force_encoding(encoding) if encoding
  data = StringIO.new(data) unless data.is_a? StringIO
  skip_header_rows.times { data.readline }
  records = data.each_with_object([]) do |row, a|
    a << parse_row(row) unless row.strip.empty?
  end
  skip_footer_rows.times { records.pop }
  records
end
row_format() click to toggle source
# File lib/stockboy/readers/fixed_width.rb, line 94
def row_format
  @row_format ||= (?A << column_widths.join(?A)).freeze
end

Private Instance Methods

column_keys() click to toggle source
# File lib/stockboy/readers/fixed_width.rb, line 107
def column_keys
  @column_keys ||= case headers
  when Hash then headers.keys.map(&:freeze)
  when Array then (0 ... headers.length).to_a
  end
end
column_widths() click to toggle source
# File lib/stockboy/readers/fixed_width.rb, line 100
def column_widths
  @column_widths ||= case headers
  when Hash then headers.values
  when Array then headers
  end
end
parse_row(row) click to toggle source
# File lib/stockboy/readers/fixed_width.rb, line 114
def parse_row(row)
  Hash[column_keys.zip(row.unpack(row_format))]
end
validate_headers() click to toggle source
# File lib/stockboy/readers/fixed_width.rb, line 118
def validate_headers
  @column_widths, @column_keys, @row_format = nil, nil, nil
  case headers
  when Hash, Array then true
  else raise ArgumentError, "Invalid headers set for #{self.class}, " \
                            "got #{headers.class}, expected Hash or Array"
  end
end