Reading CSV files using Ruby

09 Feb 2019

Ruby provides a variety of libraries for interfacing with different filetypes. Working as a web developer the library that I have used must often has definitely that developed for CSV parsing. It provides an intuitive interface for importing an manipulating CSV data. In this example I we will be creating People objects from each row of a CSV file.

// people.csv

name,age,hometown
Tina,22,London
Jim,32,Manchester
Harriet,41,Swansea

Firstly, the CSV library must be imported for use. The CSV.read function has one mandatory argument, the path to the CSV file that you would like to read, the second argument is an optional "options" hash. In the example below the first row of the CSV file is a row of headers. This has been specified in the options hash and essentially states that we do not want to include the first row when we parse the file. It will also allow us to call #to_h on the CSV row and pass that hash straight to the class Person when we instantiate it.

# person.rb

class Person 
  def initialize(args)
    @name = args['name']
    @age = args['age'].to_i
    @hometown = args['hometown']
  end

  def summarize
    puts "#{name} is #{age} years old and lives in #{hometown}."
  end

  private

  attr_reader :name, :age, :hometown
end

Parsing Each Row

In the file person.rb we have created a Person class which accepts a hash as an argument. During the initialize function of the class we then select each of the attributes we want and assign them to the instance variables for that person. We call .to_i on the age as it is parsed as a string initially. Instantiating a Person object for each row allows us to easily define methods that a person should be able to do. An example of this is the summarize function.

# csv-parser.rb
# Read the csv file and instantiate new People, then print a summary about each one

require 'csv'
require_relative './person.rb'

csv = CSV.read('people.csv', headers: true)

people = csv.map { |person| Person.new(person.to_h) }

people.map(&:summarize)

# prints 
# Tina is 22 years old and lives in London.
# Jim is 32 years old and lives in Manchester.
# Harriet is 41 years old and lives in Swansea.