I finished the Ruby chapter in Seven Languages in Seven Weeks. It tries to make you familiar with the core concepts of several languages rather quickly. Dutifully I did all exercises, but most likely they can be improved to be more ruby like. I'll post my code samples one by one, so I can apply things learned in previous questions to later questions.
Previously, Day 1
Day 2
Write a simple grep that will print the lines of a file having any occurrences of a phrase anywhere in that line (in my example 'bleh'). Include line numbers.
File.open( 'grepFile.txt', 'r' ) do |file|
lines = []
line_number = 1
file.readlines.each do |line|
lines[line_number] = line
line_number += 1
end
lines.each_index do |i|
line = lines[i]
puts "line #{i.to_s}: #{line}" if line =~ /bleh/
end
end
Since Day 2 was really short, I'll just add the (final) day 3 here as well.
Given: a CSV file structered with a first line with headers and subsequent rows with data.
one, two
lions, tigers
Create a module which loads the header and values from a CSV file, based on the name of the implementing class. (RubyCSV -> "rubycsv.txt") Support an each method which returns a CsvRow object. Use method_missing to return the value for the column for a given heading. E.g. usage which will print "lions":
m = RubyCsv.new
m.each { |row| p row.one }
My implementation:
class CsvRow
attr :row_hash
def initialize( row_hash )
@row_hash = row_hash
end
def method_missing( name, *args )
@row_hash[ name.to_s ]
end
end
module ActsAsCsv
attr_accessor :headers, :csv_contents
def self.included( base )
base.extend ClassMethods
end
module ClassMethods
def acts_as_csv
include InstanceMethods
end
end
module InstanceMethods
def read
@csv_contents = []
filename = self.class.to_s.downcase + '.txt'
file = File.new( filename )
@headers = file.gets.chomp.split( ', ' )
file.each do |row|
@csv_contents << row.chomp.split( ', ' )
end
end
def initialize
read
end
def each
@csv_contents.each do |content|
hash = {}
@headers.zip( content ).each { |i| hash[ i[0] ] = i[1] }
yield CsvRow.new hash
end
end
end
end
class RubyCsv # No inheritance! You can mix it in.
include ActsAsCsv
acts_as_csv
end