Class: Record::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/record/base.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**kwargs) ⇒ Base

Returns a new instance of Base.



125
126
127
128
# File 'lib/record/base.rb', line 125

def initialize( **kwargs )
  @values = []
  update( kwargs )
end

Class Method Details

.build_hash(values) ⇒ Object

find a better name - build_attrib? or something?



60
61
62
63
64
65
66
67
# File 'lib/record/base.rb', line 60

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?


52
# File 'lib/record/base.rb', line 52

def self.column( name, type=:string ) field( name, type ); end

.column_namesObject



54
# File 'lib/record/base.rb', line 54

def self.column_names() field_names; end

.column_typesObject



55
# File 'lib/record/base.rb', line 55

def self.column_types() field_types; end

.columnsObject



53
# File 'lib/record/base.rb', line 53

def self.columns() fields; end

.define_field(field) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/record/base.rb', line 33

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



25
26
27
28
29
30
31
# File 'lib/record/base.rb', line 25

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_namesObject

rename to header - why? why not?



11
12
13
14
15
16
# File 'lib/record/base.rb', line 11

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_typesObject



18
19
20
21
# File 'lib/record/base.rb', line 18

def self.field_types
  ##  note: types are (always) classes!!!

  fields.map {|field| field.type }
end

.fieldsObject

note: use class instance variable (@fields and NOT @@fields)!!!! (derived classes get its own copy!!!)



7
8
9
# File 'lib/record/base.rb', line 7

def self.fields   ## note: use class instance variable (@fields and NOT @@fields)!!!! (derived classes get its own copy!!!)

  @fields ||= []
end

.typecast(new_values) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/record/base.rb', line 71

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



105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/record/base.rb', line 105

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?



89
90
91
92
93
94
# File 'lib/record/base.rb', line 89

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)

  @values = self.class.typecast( new_values )
  self  ## return self for chaining

end

#to_hObject

use to_hash - why? why not? - add attributes alias - why? why not?



121
122
123
# File 'lib/record/base.rb', line 121

def to_h    ## use to_hash - why? why not?  - add attributes alias - why? why not?

  self.class.build_hash( @values )
end

#update(**kwargs) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/record/base.rb', line 130

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

#valuesObject



97
98
99
100
101
# File 'lib/record/base.rb', line 97

def values
  ## return array of all record values (typed e.g. float, integer, date, ..., that is,

  ##   as-is and  NOT auto-converted to string

  @values
end