Module: ConvertableValues::ClassMethods

Defined in:
lib/convertable_values.rb

Instance Method Summary collapse

Instance Method Details

#base_length_unitObject



92
93
94
# File 'lib/convertable_values.rb', line 92

def base_length_unit
  :meters
end

#base_mass_unitObject

Base Units ####



84
85
86
# File 'lib/convertable_values.rb', line 84

def base_mass_unit
  :kilograms
end

#base_time_unitObject



96
97
98
# File 'lib/convertable_values.rb', line 96

def base_time_unit
  :seconds
end

#base_volume_unitObject



88
89
90
# File 'lib/convertable_values.rb', line 88

def base_volume_unit
  :fluid_ounce
end

#convert(value_attr, unit_attr) ⇒ Object

Calling convert(value_attr_name, unit_attr_name) will set up that pair of value/unit attributes to automatically convert the valu to/from the given unit’s base unit.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/convertable_values.rb', line 14

def convert(value_attr, unit_attr)
  # Create override method for converting value to base unit when set
  define_method "#{value_attr}=".to_sym do |new_value|
    new_value = new_value.to_f if new_value.is_a?(String)
    unit_str = send(unit_attr.to_sym)
    
    if new_value && unit_str
      # store the value converted to the base unit corresponding to the given unit
      if respond_to?(:write_attribute, true)
        write_attribute(value_attr.to_sym, new_value.send(unit_str))
      else
        instance_variable_set("@#{value_attr}".to_sym, new_value.send(unit_str))
      end
    else
      if respond_to?(:write_attribute, true)
        write_attribute(value_attr.to_sym, new_value)
      else
        instance_variable_set("@#{value_attr}".to_sym, new_value)
      end
    end
  end
  
  # Create override method for converting value to stored unit when accessed
  define_method value_attr.to_sym do
    unit_str = send(unit_attr.to_sym)
    
    if unit_str
      # return the value converted back to whatever unit was stored
      if respond_to?(:read_attribute, true)
        read_attribute(value_attr.to_sym).to(unit_str.to_sym)
      else
        instance_variable_get("@#{value_attr}".to_sym).to(unit_str.to_sym)
      end
    else
      if respond_to?(:read_attribute, true)
        read_attribute(value_attr.to_sym)
      else
        instance_variable_get("@#{value_attr}".to_sym)
      end
    end
  end
  
  # Create override method for updating value when unit is set/changed
  define_method "#{unit_attr}=".to_sym do |new_unit|
    if respond_to?(:read_attribute, true)
      old_unit = read_attribute(unit_attr.to_sym)
    else
      old_unit = instance_variable_get("@#{unit_attr}".to_sym)
    end
    
    if respond_to?(:write_attribute, true)
      write_attribute(unit_attr.to_sym, new_unit)
    else
      instance_variable_set("@#{unit_attr}".to_sym, new_unit)
    end
  
    # Re-assign the value so it will be converted properly
    if respond_to?(:read_attribute, true)
      value = read_attribute(value_attr.to_sym)
    else
      value = instance_variable_get("@#{value_attr}".to_sym)
    end
    send("#{value_attr}=".to_sym, value) if value && old_unit.nil?

    new_unit
  end
end