<commit_before>class RapidTransit::Row
  attr_accessor :values
  attr_accessor :parser
  attr_accessor :line
  attr_accessor :num

  def initialize(parser, line, num)
    @parser = parser
    @line = line
    @num = num
    @values = extract_columns
  end

  def parse
    parser.actions.each do |action|
      apply action
    end
  end

  def apply(action)
    return unless action.apply? self
    self.values[action.key] = action.result(self)
    check_result(action)
  end

  def [](arg)
    if arg.is_a? Hash
      key, method = arg.first
      @values[key].send method
    else
      @values[arg]
    end
  end

  def []=(key, val)
    @values[key] = val
  end

private

  def check_result(action)
    unless !action.result_saved? || values[action.key] && values[action.key].id
      record = values[action.key]
      errors = record ? record.errors.full_messages.join("\n") : "Not found"
      message = "Error parsing #{action.key} on line #{num}: #{errors}\n\n" +
                parser.column_names.map {|c| "#{c}: #{values[c]}"}.join("\n")
      raise RapidTransit::NotFoundError, message, caller
    end
  end

  def extract_columns
    columns = line.split(parser.delimiter)
    columns = columns.map(&:strip) if parser.strip
    unless columns.count == parser.column_names.count
      message = "Wrong number of columns in line #{num}:\n#{line}\n" +
                "(Expected columns: #{parser.column_names.join(", ")})"
      raise RapidTransit::ColumnMismatchError, message, caller
    end
    array = parser.column_names.zip(columns).map { |key, value| [key, value] }
    Hash[array]
  end

end<commit_msg>Expose input values hash<commit_after>class RapidTransit::Row
  attr_accessor :values
  attr_accessor :parser
  attr_accessor :line
  attr_accessor :num

  def initialize(parser, line, num)
    @parser = parser
    @line = line
    @num = num
    @values = input_values
  end

  def parse
    parser.actions.each do |action|
      apply action
    end
  end

  def apply(action)
    return unless action.apply? self
    self.values[action.key] = action.result(self)
    check_result(action)
  end

  def [](arg)
    if arg.is_a? Hash
      key, method = arg.first
      @values[key].send method
    else
      @values[arg]
    end
  end

  def []=(key, val)
    @values[key] = val
  end

  def input_values
    columns = line.split(parser.delimiter)
    columns = columns.map(&:strip) if parser.strip
    unless columns.count == parser.column_names.count
      message = "Wrong number of columns in line #{num}:\n#{line}\n" +
                "(Expected columns: #{parser.column_names.join(", ")})"
      raise RapidTransit::ColumnMismatchError, message, caller
    end
    array = parser.column_names.zip(columns).map { |key, value| [key, value] }
    Hash[array]
  end

private

  def check_result(action)
    unless !action.result_saved? || values[action.key] && values[action.key].id
      record = values[action.key]
      errors = record ? record.errors.full_messages.join("\n") : "Not found"
      message = "Error parsing #{action.key} on line #{num}: #{errors}\n"
      raise RapidTransit::NotFoundError, message, caller
    end
  end

end
{'fraction_non_alphanumeric': 0.12267423525701672, 'fraction_numerical': 0.0, 'mean_word_length': 2.945273631840796, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6403979', 'n_tokens_mistral': 1031, 'n_tokens_neox': 1008, 'n_words': 258}