Class: Weighable::Weight
- Inherits:
-
Object
- Object
- Weighable::Weight
- Includes:
- Comparable
- Defined in:
- lib/weighable/weight.rb
Constant Summary collapse
- UNIT =
{ gram: 0, ounce: 1, pound: 2, milligram: 3, kilogram: 4, unit: 5, fluid_ounce: 6 }.freeze
- UNIT_ABBREVIATION =
{ gram: 'g', ounce: 'oz', pound: 'lb', milligram: 'mg', kilogram: 'kg', fluid_ounce: 'fl oz', unit: nil }.freeze
- ABBREVIATION_ALIASES =
{ 'g' => :gram, 'oz' => :ounce, 'lb' => :pound, 'mg' => :milligram, 'kg' => :kilogram, 'fl oz' => :fluid_ounce, 'ea' => :unit, 'each' => :unit, nil => :unit }.freeze
- GRAMS_PER_OUNCE =
BigDecimal.new('28.34952')
- GRAMS_PER_POUND =
BigDecimal.new('453.59237')
- OUNCES_PER_POUND =
BigDecimal.new('16')
- MILLIGRAMS_PER_GRAM =
BigDecimal.new('1000')
- KILOGRAMS_PER_GRAM =
BigDecimal.new('0.001')
- IDENTITY =
BigDecimal.new('1')
- MILLIGRAMS_PER_OUNCE =
GRAMS_PER_OUNCE * MILLIGRAMS_PER_GRAM
- KILOGRAMS_PER_OUNCE =
GRAMS_PER_OUNCE * KILOGRAMS_PER_GRAM
- MILLIGRAMS_PER_POUND =
GRAMS_PER_POUND * MILLIGRAMS_PER_GRAM
- KILOGRAMS_PER_POUND =
GRAMS_PER_POUND * KILOGRAMS_PER_GRAM
- MILLIGRAMS_PER_KILOGRAM =
MILLIGRAMS_PER_GRAM**2
- FLUID_OUNCE_PER_OUNCE =
IDENTITY
- CONVERSIONS =
{ UNIT[:unit] => { UNIT[:unit] => [:*, IDENTITY] }, UNIT[:gram] => { UNIT[:gram] => [:*, IDENTITY], UNIT[:ounce] => [:/, GRAMS_PER_OUNCE], UNIT[:pound] => [:/, GRAMS_PER_POUND], UNIT[:milligram] => [:*, MILLIGRAMS_PER_GRAM], UNIT[:kilogram] => [:*, KILOGRAMS_PER_GRAM], UNIT[:fluid_ounce] => [:/, GRAMS_PER_OUNCE] }, UNIT[:ounce] => { UNIT[:gram] => [:*, GRAMS_PER_OUNCE], UNIT[:ounce] => [:*, IDENTITY], UNIT[:pound] => [:/, OUNCES_PER_POUND], UNIT[:milligram] => [:*, MILLIGRAMS_PER_OUNCE], UNIT[:kilogram] => [:*, KILOGRAMS_PER_OUNCE], UNIT[:fluid_ounce] => [:*, IDENTITY] }, UNIT[:pound] => { UNIT[:gram] => [:*, GRAMS_PER_POUND], UNIT[:ounce] => [:*, OUNCES_PER_POUND], UNIT[:pound] => [:*, IDENTITY], UNIT[:milligram] => [:*, MILLIGRAMS_PER_POUND], UNIT[:kilogram] => [:*, KILOGRAMS_PER_POUND], UNIT[:fluid_ounce] => [:*, OUNCES_PER_POUND] }, UNIT[:milligram] => { UNIT[:gram] => [:/, MILLIGRAMS_PER_GRAM], UNIT[:ounce] => [:/, MILLIGRAMS_PER_OUNCE], UNIT[:pound] => [:/, MILLIGRAMS_PER_POUND], UNIT[:milligram] => [:*, IDENTITY], UNIT[:kilogram] => [:/, MILLIGRAMS_PER_KILOGRAM], UNIT[:fluid_ounce] => [:/, MILLIGRAMS_PER_OUNCE] }, UNIT[:kilogram] => { UNIT[:gram] => [:/, KILOGRAMS_PER_GRAM], UNIT[:ounce] => [:/, KILOGRAMS_PER_OUNCE], UNIT[:pound] => [:/, KILOGRAMS_PER_POUND], UNIT[:milligram] => [:*, MILLIGRAMS_PER_KILOGRAM], UNIT[:kilogram] => [:*, IDENTITY], UNIT[:fluid_ounce] => [:/, KILOGRAMS_PER_OUNCE] }, UNIT[:fluid_ounce] => { UNIT[:fluid_ounce] => [:*, IDENTITY], UNIT[:gram] => [:*, GRAMS_PER_OUNCE], UNIT[:ounce] => [:*, IDENTITY], UNIT[:pound] => [:/, OUNCES_PER_POUND], UNIT[:milligram] => [:*, MILLIGRAMS_PER_OUNCE], UNIT[:kilogram] => [:*, KILOGRAMS_PER_OUNCE], } }.freeze
Instance Attribute Summary collapse
-
#unit ⇒ Object
readonly
Returns the value of attribute unit.
-
#value ⇒ Object
readonly
Returns the value of attribute value.
Class Method Summary collapse
Instance Method Summary collapse
- #*(other) ⇒ Object
- #+(other) ⇒ Object
- #-(other) ⇒ Object
- #/(other) ⇒ Object
- #<(other) ⇒ Object
- #<=(other) ⇒ Object
- #<=>(other) ⇒ Object
- #==(other) ⇒ Object
- #>(other) ⇒ Object
- #>=(other) ⇒ Object
- #abs ⇒ Object
- #ceil(precision = 0) ⇒ Object
- #floor(precision = 0) ⇒ Object
-
#initialize(value, unit) ⇒ Weight
constructor
A new instance of Weight.
- #round(precision = 0) ⇒ Object
- #to(unit) ⇒ Object
- #to_s(only_unit: false) ⇒ Object
- #zero? ⇒ Boolean
Constructor Details
#initialize(value, unit) ⇒ Weight
Returns a new instance of Weight.
133 134 135 136 |
# File 'lib/weighable/weight.rb', line 133 def initialize(value, unit) @value = value.to_d @unit = unit.is_a?(Fixnum) ? unit : unit_from_symbol(unit.to_sym) end |
Instance Attribute Details
#unit ⇒ Object (readonly)
Returns the value of attribute unit.
7 8 9 |
# File 'lib/weighable/weight.rb', line 7 def unit @unit end |
#value ⇒ Object (readonly)
Returns the value of attribute value.
7 8 9 |
# File 'lib/weighable/weight.rb', line 7 def value @value end |
Class Method Details
.from_value_and_unit(value, unit) ⇒ Object
121 122 123 124 125 |
# File 'lib/weighable/weight.rb', line 121 def self.from_value_and_unit(value, unit) unit = parse_unit(unit) fail ArgumentError, 'invalid weight' if unit.nil? || value.to_s.strip.empty? Weight.new(value, unit) end |
.parse(string) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/weighable/weight.rb', line 109 def self.parse(string) trimmed = string.strip unit_start = trimmed.index(' ') if unit_start unit = trimmed.slice!(unit_start + 1..-1) value = trimmed.slice!(0..unit_start - 1) from_value_and_unit(value, unit) else from_value_and_unit(trimmed, nil) end end |
.parse_unit(unit) ⇒ Object
127 128 129 130 131 |
# File 'lib/weighable/weight.rb', line 127 def self.parse_unit(unit) unit = ActiveSupport::Inflector.singularize(unit.downcase) unless unit.nil? unit_symbol = unit ? unit.tr(' ', '_').to_sym : unit UNIT[unit_symbol] || ABBREVIATION_ALIASES[unit] end |
Instance Method Details
#*(other) ⇒ Object
178 179 180 |
# File 'lib/weighable/weight.rb', line 178 def *(other) Weight.new(@value * to_math_value(other), unit_name) end |
#+(other) ⇒ Object
168 169 170 171 |
# File 'lib/weighable/weight.rb', line 168 def +(other) other = other.to(unit_name) Weight.new(@value + other.value, unit_name) end |
#-(other) ⇒ Object
173 174 175 176 |
# File 'lib/weighable/weight.rb', line 173 def -(other) other = other.to(unit_name) Weight.new(@value - other.value, unit_name) end |
#/(other) ⇒ Object
182 183 184 185 186 187 188 189 |
# File 'lib/weighable/weight.rb', line 182 def /(other) if !other.is_a?(Weight) || (other.is_unit? && other.unit != @unit) Weight.new(@value / to_math_value(other), unit_name) else other = other.to(unit_name) BigDecimal.new(@value / other.value) end end |
#<(other) ⇒ Object
195 196 197 198 |
# File 'lib/weighable/weight.rb', line 195 def <(other) other = other.to(unit_name) @value < other.value end |
#<=(other) ⇒ Object
200 201 202 203 |
# File 'lib/weighable/weight.rb', line 200 def <=(other) other = other.to(unit_name) @value <= other.value end |
#<=>(other) ⇒ Object
215 216 217 218 |
# File 'lib/weighable/weight.rb', line 215 def <=>(other) other = other.to(unit_name) @value <=> other.value end |
#==(other) ⇒ Object
191 192 193 |
# File 'lib/weighable/weight.rb', line 191 def ==(other) other.class == self.class && other.value == @value && other.unit == @unit end |
#>(other) ⇒ Object
205 206 207 208 |
# File 'lib/weighable/weight.rb', line 205 def >(other) other = other.to(unit_name) @value > other.value end |
#>=(other) ⇒ Object
210 211 212 213 |
# File 'lib/weighable/weight.rb', line 210 def >=(other) other = other.to(unit_name) @value >= other.value end |
#abs ⇒ Object
232 233 234 |
# File 'lib/weighable/weight.rb', line 232 def abs Weight.new(@value.abs, @unit) end |
#ceil(precision = 0) ⇒ Object
224 225 226 |
# File 'lib/weighable/weight.rb', line 224 def ceil(precision = 0) Weight.new(@value.ceil(precision), @unit) end |
#floor(precision = 0) ⇒ Object
228 229 230 |
# File 'lib/weighable/weight.rb', line 228 def floor(precision = 0) Weight.new(@value.floor(precision), @unit) end |
#round(precision = 0) ⇒ Object
220 221 222 |
# File 'lib/weighable/weight.rb', line 220 def round(precision = 0) Weight.new(@value.round(precision), @unit) end |
#to(unit) ⇒ Object
138 139 140 141 142 143 |
# File 'lib/weighable/weight.rb', line 138 def to(unit) new_unit = unit.is_a?(Fixnum) ? unit : unit_from_symbol(unit.to_sym) operator, conversion = conversion(@unit, new_unit) new_value = @value.public_send(operator, conversion) Weight.new(new_value, unit) end |
#to_s(only_unit: false) ⇒ Object
159 160 161 162 163 164 165 166 |
# File 'lib/weighable/weight.rb', line 159 def to_s(only_unit: false) if only_unit unit_abbreviation.to_s else value = @value.to_f == @value.to_i ? @value.to_i : @value.to_f [value, unit_abbreviation].compact.join(' ') end end |
#zero? ⇒ Boolean
236 237 238 |
# File 'lib/weighable/weight.rb', line 236 def zero? @value.zero? end |