It's me!

Jezen Thomas

Founder of NewBusinessMonitor

Programmer at Zimpler

Ruby Day Three

On the third day of Ruby, we looked at metaprogramming with open classes, modules, macros and the method_missing method.

  1. An improved CSV parser
  2. The original code
  3. Specification
  4. Implementation
  5. Thoughts

An improved CSV parser

Mody the CSV application to support an each method to return a CsvRow object. Use method_missing on that CsvRow to return the value for the column for a given heading.

The original code

For the sake of completeness, I’ve included the original application code that we’re given to use as a starting point.

module ActsAsCsv
  def self.included(base)
    base.extend ClassMethods

  module ClassMethods
    def acts_as_csv
      include InstanceMethods

  module InstanceMethods
    def read
      @csv_contents = []
      filename = self.class.to_s.downcase + '.txt'
      file =
      @headers = file.gets.chomp.split(', ')

      file.each do |row|
        @csv_contents << row.chomp.split(', ')

    attr_accessor :headers, :csv_contents
    def initialize

class RubyCsv
  include ActsAsCsv


We’re given a specification of how the API should work; the API should allow you to fetch data with, one being the name of the column to retrieve each row’s value from.

csv =
csv.each {|row| puts}


In the wild, I imagine a module you include in a class would be written by someone else. It’s a library, it’s a collection of helpful things, it’s modular. For that reason, I added my implementation to the RubyCsv class and left the ActsAsCsv module untouched.

The first step was to define an each method, which creates new instances of CsvRow. Of course following that, I would have to write a CsvRow class. This class accepts the CSV column headers, and each row. The method_missing method takes a name, finds the index of that name in the array of column headers, and returns the value at that index for each row.

Since I only changed the RubyCsv class, I’ll only include that code.

class RubyCsv
  include ActsAsCsv

  class CsvRow
    def initialize headers, rows
      @headers = headers
      @rows = rows

    def method_missing name
      index = @headers.index name.to_s

  def each &block
    @csv_contents.each do |row| @headers, row


Metaprogramming is interesting, but I think we only touched very lightly on the topic and some more challenges would have been welcome. After completing this challenge, I had a better understanding of how ActiveRecord works in Ruby on Rails.

Working with Ruby is painless. I like the terse syntax and the flexible list comprehension. It feels as though I’m worrying less about micromanagement, and focusing more on writing a simple script that does something.