Skip to content

Instantly share code, notes, and snippets.

@mmmries
Created January 16, 2014 16:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmmries/8458417 to your computer and use it in GitHub Desktop.
Save mmmries/8458417 to your computer and use it in GitHub Desktop.
Convenient CSV My solution for the homework assignment from the end of chapter 2 in the [Seven Languages in Seven Weeks](http://pragprog.com/book/btlang/seven-languages-in-seven-weeks) book
module ActsAsCsv
def read
@csv_contents = []
filename = self.class.to_s.downcase + '.csv'
file = File.new(filename)
@headers = file.gets.chomp.split(', ')
file.each do |row|
@csv_contents << row.chomp.split(', ')
end
end
def each
csv_contents.each do |row|
yield CsvRow.new(headers, row)
end
end
attr_accessor :headers, :csv_contents
def initialize
read
end
end
class CsvRow
attr_reader :headers, :contents
def initialize(headers,contents)
@headers, @contents = headers, contents
end
def method_missing(*args)
key = args.first.to_s
idx = headers.index(key)
contents[idx]
end
end
module ActsAsCsv
def read
@csv_contents = []
filename = self.class.to_s.downcase + '.csv'
file = File.new(filename)
@headers = file.gets.chomp.split(', ')
file.each do |row|
@csv_contents << row.chomp.split(', ')
end
end
def each
csv_contents.each do |row|
yield row_struct.new(*row)
end
end
attr_accessor :headers, :csv_contents
def initialize
read
end
private
def row_struct
@row_struct ||= Struct.new(*headers.map(&:to_sym))
end
end
name sound eats
lion roar everything
tiger growl humans
hippo (bubbles) underwater vegetation
require 'acts_as_csv'
class Animals
include ActsAsCsv
end
animals = Animals.new
animals.each do |animal|
puts "the #{animal.name} says #{animal.sound} right before he eats #{animal.eats}"
end
@mmmries
Copy link
Author

mmmries commented Jan 16, 2014

First thing I did was get rid of the whole self.included and ClassMethods thing from ActsAsCsv since it was only being used to include the instance methods which is what normally happens when you include a module anyway.

Then I wrote a class CsvRow as suggested in the book. But I thought the method_missing was a bit wonky.

So my acts_as_csv.v2.rb uses Struct to create its own little private class for the parsed csv class and then just inflates each row into an instance of that private class. I like that better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment