using AIXM::Refinements module AIXM # Weight # # @example # AIXM.w(2.9, :t) class W include AIXM::Concerns::HashEquality include Comparable extend Forwardable UNITS = { kg: { t: 0.001, lb: 2.204622622, ton: 0.00110231131 }, t: { kg: 1000, lb: 2204.622622, ton: 1.10231131 }, lb: { kg: 0.45359237, t: 0.00045359237, ton: 0.000499999999581 }, ton: { kg: 907.18474, t: 0.90718474, lb: 2000.00000013718828 } }.freeze # Whether weight is zero. # # @!method zero? # @return [Boolean] def_delegator :@wgt, :zero? # Weight # # @overload wgt # @return [Float] # @overload wgt=(value) # @param value [Float] attr_reader :wgt # Unit # # @overload unit # @return [Float] any of {UNITS} # @overload unit=(value) # @param value [Float] any of {UNITS} attr_reader :unit # See the {overview}[AIXM::W] for examples. def initialize(wgt, unit) self.wgt, self.unit = wgt, unit end # @return [String] def inspect %Q(#<#{self.class} #{to_s}>) end # @return [String] human readable representation (e.g. "123 t") def to_s [wgt, unit].join(' '.freeze) end def wgt=(value) fail(ArgumentError, "invalid wgt") unless value.is_a?(Numeric) && value >= 0 @wgt = value.to_f end def unit=(value) fail(ArgumentError, "invalid unit") unless value.respond_to? :to_sym @unit = value.to_sym.downcase fail(ArgumentError, "invalid unit") unless UNITS.has_key? @unit end # Convert weight # # @!method to_kg # @!method to_t # @!method to_lb # @!method to_ton # @return [AIXM::W] converted weight UNITS.each_key do |target_unit| define_method "to_#{target_unit}" do return self if unit == target_unit self.class.new((wgt * UNITS[unit][target_unit]).round(8), target_unit) end end # @see Object#<=> def <=>(other) wgt <=> other.send(:"to_#{unit}").wgt end # @see Object#== def ==(other) self.class === other && (self <=> other).zero? end end end