Class: CsvRecord::Base
- Inherits:
-
Object
- Object
- CsvRecord::Base
- Defined in:
- lib/csvrecord/base.rb
Class Method Summary collapse
-
.build_hash(values) ⇒ Object
find a better name - build_attrib? or something?.
-
.column(name, type = :string) ⇒ Object
column/columns aliases for field/fields use self << with alias_method - possible? works? why? why not?.
- .column_names ⇒ Object
- .column_types ⇒ Object
- .columns ⇒ Object
- .define_field(field) ⇒ Object
- .field(name, type = :string) ⇒ Object
-
.field_names ⇒ Object
rename to header - why? why not?.
- .field_types ⇒ Object
-
.fields ⇒ Object
note: use class instance variable (@fields and NOT @@fields)!!!! (derived classes get its own copy!!!).
- .foreach(path, sep: Csv.config.sep, headers: true) ⇒ Object
-
.parse(txt_or_rows, sep: Csv.config.sep, headers: true) ⇒ Object
note: returns an (lazy) enumarator.
-
.read(path, sep: Csv.config.sep, headers: true) ⇒ Object
not returns an enumarator.
- .typecast(new_values) ⇒ Object
Instance Method Summary collapse
- #[](key) ⇒ Object
-
#initialize(**kwargs) ⇒ Base
constructor
A new instance of Base.
-
#parse(new_values) ⇒ Object
use read (from array) or read_values or read_row - why? why not?.
-
#to_csv ⇒ Object
use/rename/alias to to_row too - why? why not?.
-
#to_h ⇒ Object
use to_hash - why? why not? - add attributes alias - why? why not?.
- #update(**kwargs) ⇒ Object
- #values ⇒ Object
Constructor Details
#initialize(**kwargs) ⇒ Base
Returns a new instance of Base.
312 313 314 315 |
# File 'lib/csvrecord/base.rb', line 312 def initialize( **kwargs ) @values = [] update( kwargs ) end |
Class Method Details
.build_hash(values) ⇒ Object
find a better name - build_attrib? or something?
193 194 195 196 197 198 199 200 |
# File 'lib/csvrecord/base.rb', line 193 def self.build_hash( values ) ## find a better name - build_attrib? or something? ## convert to key-value (attribute) pairs ## puts "== build_hash:" ## pp values ## e.g. [[],[]] return zipped pairs in array as (attribute - name/value pair) hash Hash[ field_names.zip(values) ] end |
.column(name, type = :string) ⇒ Object
column/columns aliases for field/fields
use self << with alias_method - possible? works? why? why not?
185 |
# File 'lib/csvrecord/base.rb', line 185 def self.column( name, type=:string ) field( name, type ); end |
.column_names ⇒ Object
187 |
# File 'lib/csvrecord/base.rb', line 187 def self.column_names() field_names; end |
.column_types ⇒ Object
188 |
# File 'lib/csvrecord/base.rb', line 188 def self.column_types() field_types; end |
.columns ⇒ Object
186 |
# File 'lib/csvrecord/base.rb', line 186 def self.columns() fields; end |
.define_field(field) ⇒ Object
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/csvrecord/base.rb', line 166 def self.define_field( field ) name = field.name ## note: always assumes a "cleaned-up" (symbol) name num = field.num define_method( name ) do instance_variable_get( "@values" )[num] end define_method( "#{name}=" ) do |value| instance_variable_get( "@values" )[num] = value end define_method( "parse_#{name}") do |value| instance_variable_get( "@values" )[num] = field.typecast( value ) end end |
.field(name, type = :string) ⇒ Object
158 159 160 161 162 163 164 |
# File 'lib/csvrecord/base.rb', line 158 def self.field( name, type=:string ) num = fields.size ## auto-calc num(ber) / position index - always gets added at the end field = Field.new( name, num, type ) fields << field define_field( field ) ## auto-add getter,setter,parse/typecast end |
.field_names ⇒ Object
rename to header - why? why not?
144 145 146 147 148 149 |
# File 'lib/csvrecord/base.rb', line 144 def self.field_names ## rename to header - why? why not? ## return header row, that is, all field names in an array ## todo: rename to field_names or just names - why? why not? ## note: names are (always) symbols!!! fields.map {|field| field.name } end |
.field_types ⇒ Object
151 152 153 154 |
# File 'lib/csvrecord/base.rb', line 151 def self.field_types ## note: types are (always) classes!!! fields.map {|field| field.type } end |
.fields ⇒ Object
note: use class instance variable (@fields and NOT @@fields)!!!! (derived classes get its own copy!!!)
140 141 142 |
# File 'lib/csvrecord/base.rb', line 140 def self.fields ## note: use class instance variable (@fields and NOT @@fields)!!!! (derived classes get its own copy!!!) @fields ||= [] end |
.foreach(path, sep: Csv.config.sep, headers: true) ⇒ Object
271 272 273 274 275 276 277 278 279 |
# File 'lib/csvrecord/base.rb', line 271 def self.foreach( path, sep: Csv.config.sep, headers: true ) CsvReader.foreach( path, sep: sep, headers: headers ) do |row| rec = new values = CsvReader.unwrap( row ) rec.parse( values ) yield( rec ) ## check: use block.class( rec ) - why? why not? end end |
.parse(txt_or_rows, sep: Csv.config.sep, headers: true) ⇒ Object
note: returns an (lazy) enumarator
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/csvrecord/base.rb', line 282 def self.parse( txt_or_rows, sep: Csv.config.sep, headers: true ) ## note: returns an (lazy) enumarator if txt_or_rows.is_a? String txt = txt_or_rows rows = CsvReader.parse( txt, sep: sep, headers: headers ) else ### todo/fix: use only self.create( array-like ) for array-like data - why? why not? rows = txt_or_rows ## assume array-like records that responds to :each end pp rows Enumerator.new do |yielder| rows.each do |row| rec = new values = CsvReader.unwrap( row ) rec.parse( values ) yielder.yield( rec ) end end end |
.read(path, sep: Csv.config.sep, headers: true) ⇒ Object
not returns an enumarator
305 306 307 308 |
# File 'lib/csvrecord/base.rb', line 305 def self.read( path, sep: Csv.config.sep, headers: true ) ## not returns an enumarator txt = File.open( path, 'r:utf-8' ).read parse( txt, sep: sep, headers: headers ) end |
.typecast(new_values) ⇒ Object
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/csvrecord/base.rb', line 204 def self.typecast( new_values ) values = [] ## ## todo: check that new_values.size <= fields.size ## ## fields without values will get auto-filled with nils (or default field values?) ## ## use fields.zip( new_values ).map |field,value| ... instead - why? why not? fields.each_with_index do |field,i| value = new_values[i] ## note: returns nil if new_values.size < fields.size values << field.typecast( value ) end values end |
Instance Method Details
#[](key) ⇒ Object
244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/csvrecord/base.rb', line 244 def [](key) if key.is_a? Integer @values[ key ] elsif key.is_a? Symbol ## try attribute access send( key ) else ## assume string ## downcase and symbol-ize ## remove spaces too -why? why not? ## todo/fix: add a lookup mapping for (string) titles (Team 1, etc.) send( key.downcase.to_sym ) end end |
#parse(new_values) ⇒ Object
use read (from array) or read_values or read_row - why? why not?
222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/csvrecord/base.rb', line 222 def parse( new_values ) ## use read (from array) or read_values or read_row - why? why not? ## todo: check if values overshadowing values attrib is ok (without warning?) - use just new_values (not values) ## todo/fix: ## check if values is a string ## use Csv.parse_line to convert to array ## otherwise assume array of (string) values @values = self.class.typecast( new_values ) self ## return self for chaining end |
#to_csv ⇒ Object
use/rename/alias to to_row too - why? why not?
265 266 267 268 |
# File 'lib/csvrecord/base.rb', line 265 def to_csv ## use/rename/alias to to_row too - why? why not? ## todo/fix: check for date and use own date to string format!!!! @values.map{ |value| value.to_s } end |
#to_h ⇒ Object
use to_hash - why? why not? - add attributes alias - why? why not?
260 261 262 |
# File 'lib/csvrecord/base.rb', line 260 def to_h ## use to_hash - why? why not? - add attributes alias - why? why not? self.class.build_hash( @values ) end |
#update(**kwargs) ⇒ Object
317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
# File 'lib/csvrecord/base.rb', line 317 def update( **kwargs ) pp kwargs kwargs.each do |name,value| ## note: only convert/typecast string values if value.is_a?( String ) send( "parse_#{name}", value ) ## note: use parse_<name> setter (for typecasting) else ## use "regular" plain/classic attribute setter send( "#{name}=", value ) end end ## todo: check if args.first is an array (init/update from array) self ## return self for chaining end |
#values ⇒ Object
235 236 237 238 239 240 |
# File 'lib/csvrecord/base.rb', line 235 def values ## return array of all record values (typed e.g. float, integer, date, ..., that is, ## as-is and NOT auto-converted to string ## use to_csv or values for all string values) @values end |