class Weighable::Weight

Constants

ABBREVIATION_ALIASES
CONVERSIONS
FLUID_OUNCE_PER_OUNCE
GRAMS_PER_OUNCE
GRAMS_PER_POUND
IDENTITY
KILOGRAMS_PER_GRAM
KILOGRAMS_PER_OUNCE
KILOGRAMS_PER_POUND
MILLIGRAMS_PER_GRAM
MILLIGRAMS_PER_KILOGRAM
MILLIGRAMS_PER_OUNCE
MILLIGRAMS_PER_POUND
OUNCES_PER_POUND
UNIT
UNIT_ABBREVIATION

Attributes

unit[R]
value[R]

Public Class Methods

from_value_and_unit(value, unit) click to toggle source
# 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
new(value, unit) click to toggle source
# 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
parse(string) click to toggle source
# 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) click to toggle source
# 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

Public Instance Methods

*(other) click to toggle source
# File lib/weighable/weight.rb, line 178
def *(other)
  Weight.new(@value * to_math_value(other), unit_name)
end
+(other) click to toggle source
# File lib/weighable/weight.rb, line 168
def +(other)
  other = other.to(unit_name)
  Weight.new(@value + other.value, unit_name)
end
-(other) click to toggle source
# File lib/weighable/weight.rb, line 173
def -(other)
  other = other.to(unit_name)
  Weight.new(@value - other.value, unit_name)
end
/(other) click to toggle source
# 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(@value / other.value)
  end
end
<(other) click to toggle source
# File lib/weighable/weight.rb, line 195
def <(other)
  other = other.to(unit_name)
  @value < other.value
end
<=(other) click to toggle source
# File lib/weighable/weight.rb, line 200
def <=(other)
  other = other.to(unit_name)
  @value <= other.value
end
<=>(other) click to toggle source
# File lib/weighable/weight.rb, line 215
def <=>(other)
  other = other.to(unit_name)
  @value <=> other.value
end
==(other) click to toggle source
# File lib/weighable/weight.rb, line 191
def ==(other)
  other.class == self.class && other.value == @value && other.unit == @unit
end
>(other) click to toggle source
# File lib/weighable/weight.rb, line 205
def >(other)
  other = other.to(unit_name)
  @value > other.value
end
>=(other) click to toggle source
# File lib/weighable/weight.rb, line 210
def >=(other)
  other = other.to(unit_name)
  @value >= other.value
end
abs() click to toggle source
# File lib/weighable/weight.rb, line 232
def abs
  Weight.new(@value.abs, @unit)
end
ceil(precision = 0) click to toggle source
# File lib/weighable/weight.rb, line 224
def ceil(precision = 0)
  Weight.new(@value.ceil(precision), @unit)
end
floor(precision = 0) click to toggle source
# File lib/weighable/weight.rb, line 228
def floor(precision = 0)
  Weight.new(@value.floor(precision), @unit)
end
round(precision = 0) click to toggle source
# File lib/weighable/weight.rb, line 220
def round(precision = 0)
  Weight.new(@value.round(precision), @unit)
end
to(unit) click to toggle source
# 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) click to toggle source
# 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?() click to toggle source
# File lib/weighable/weight.rb, line 236
def zero?
  @value.zero?
end

Private Instance Methods

conversion(from, to) click to toggle source
# File lib/weighable/weight.rb, line 270
def conversion(from, to)
  conversion = CONVERSIONS[from][to]
  unless conversion
    fail NoConversionError, "no conversion from #{unit_from_int(from)} to #{unit_from_int(to)}"
  end
  conversion
end
to_math_value(other) click to toggle source
# File lib/weighable/weight.rb, line 242
def to_math_value(other)
  if other.is_a?(Weight) && other.is_unit?
    other.value
  elsif other.is_a?(Weight)
    other.to(unit_name).value
  else
    other
  end
end
unit_abbreviation() click to toggle source
# File lib/weighable/weight.rb, line 256
def unit_abbreviation
  UNIT_ABBREVIATION[unit_from_int(@unit)]
end
unit_from_int(int) click to toggle source
# File lib/weighable/weight.rb, line 266
def unit_from_int(int)
  UNIT.find { |_k, v| v == int }.first
end
unit_from_symbol(unit) click to toggle source
# File lib/weighable/weight.rb, line 260
def unit_from_symbol(unit)
  unit = UNIT[unit]
  fail "invalid unit '#{unit}'" unless unit
  unit
end
unit_name() click to toggle source
# File lib/weighable/weight.rb, line 252
def unit_name
  unit_from_int(@unit)
end