Class: CSVobj
- Inherits:
-
Object
- Object
- CSVobj
- Defined in:
- lib/csvobj.rb
Overview
This class represents each row of a CSV file as an object in an array. Object attributes are automatically created from the header (first) row in the CSV. Note that this class dynamically redefines its own attributes and constructor so you should subclass it for any remotely serious work.
Class Method Summary collapse
-
.header_to_attr(header) ⇒ Object
Convert a header (string) value to a an attribute symbol: Remove leading and trailing whitespace; replace (repeated) non-word characters with a single underscore; prefix leading digit with underscore; remove repeated adjacent underscores; convert to a lower-case symbol.
-
.parse(csv) ⇒ Object
Parse the given CSV, which may be a multi-line string or IO object (see #parse_s) or an array of row arrays (see #parse_a) and return an array of CSVobjs.
-
.parse_a(rows) ⇒ Object
Interpret an array (rows) of arrays (cells) and return an array of CSVobjs.
-
.parse_s(csv) ⇒ Object
Interpret the given multi-line string or IO object of CSV records and return an array of CSVobjs.
Instance Method Summary collapse
-
#to_a ⇒ Object
Return an array of (string) values for this CSV object in the order that they were given.
-
#to_s ⇒ Object
Return a CSV string representing this object.
-
#to_s_with_headers ⇒ Object
Return a CSV string representing this object including an initial line of headers as originally given on object creation.
Class Method Details
.header_to_attr(header) ⇒ Object
Convert a header (string) value to a an attribute symbol: Remove leading and trailing whitespace; replace (repeated) non-word characters with a single underscore; prefix leading digit with underscore; remove repeated adjacent underscores; convert to a lower-case symbol.
75 76 77 78 79 80 81 82 |
# File 'lib/csvobj.rb', line 75 def self.header_to_attr(header) header.strip. # remove trailing and leading whitespace gsub(/\W+/, '_'). # substitute underscore for non-word/digit characters sub(/^(\d)/, '_\1'). # if starts with a digit insert a leading underscore gsub(/_+/, '_'). # remove duplicate adjacent underscores downcase. # convert to lower case to_sym # convert to symbol end |
.parse(csv) ⇒ Object
Parse the given CSV, which may be a multi-line string or IO object (see #parse_s) or an array of row arrays (see #parse_a) and return an array of CSVobjs. Expects the first row to be the headers (these are used for the objects’ attributes).
22 23 24 |
# File 'lib/csvobj.rb', line 22 def self.parse(csv) csv.is_a?(Array) ? parse_a(csv) : parse_s(csv) end |
.parse_a(rows) ⇒ Object
Interpret an array (rows) of arrays (cells) and return an array of CSVobjs. Expects the first row to be the headers (these are used for the objects’ attributes).
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/csvobj.rb', line 39 def self.parse_a(rows) return [] if rows.empty? # Get attributes from first row. headers = rows.shift attr_symbols = headers.map{ |header| header_to_attr(header) } dupes = attr_symbols.uniq! raise CSVobjDuplicateHeader, "Duplicate derived headers\n#{dupes}" if dupes # Declare attributes and constructor. This will take the form: # #new(header1, header2, ...). instance_variables = attr_symbols.map{ |attr| "@#{attr}" } class_eval do attr_accessor(*attr_symbols) define_method :initialize do |*args| instance_variables.zip(args).each do |instance_variable, arg| instance_variable_set(instance_variable, arg) end end end # Define class method #headers to return an array of the (unmangled) # CSV headers by defining the method on the metaclass. (class << self ; self end).send(:define_method, :headers) { headers } # Create and return array of CSVobj, one element for each CSV row # (minus the headers). rows.map { |row| new(*row) } end |
.parse_s(csv) ⇒ Object
Interpret the given multi-line string or IO object of CSV records and return an array of CSVobjs. Expects the first row to be the headers (these are used for the objects’ attributes).
30 31 32 33 |
# File 'lib/csvobj.rb', line 30 def self.parse_s(csv) rows = s_to_a(csv) parse_a(rows) end |
Instance Method Details
#to_a ⇒ Object
Return an array of (string) values for this CSV object in the order that they were given. See dynamically defined method headers to get the equivalent array of headers.
87 88 89 90 91 92 |
# File 'lib/csvobj.rb', line 87 def to_a self.class.headers.map do |header| attr = self.class.header_to_attr(header) send(attr) end end |
#to_s ⇒ Object
Return a CSV string representing this object. Does not include headers (see #to_s_with_headers).
96 97 98 |
# File 'lib/csvobj.rb', line 96 def to_s a_to_s(to_a) end |
#to_s_with_headers ⇒ Object
Return a CSV string representing this object including an initial line of headers as originally given on object creation.
102 103 104 |
# File 'lib/csvobj.rb', line 102 def to_s_with_headers a_to_s(self.class.headers) + to_s end |