Sha256: 6dda804f824188e45d561e60e2111d7cb3e9e58c9f435b30e2b18388a1223283

Contents?: true

Size: 1.89 KB

Versions: 2

Compression:

Stored size: 1.89 KB

Contents

module Reality
  class Measure
    %w[unit].each{|mod| require_relative "measure/#{mod}"}
    
    attr_reader :amount, :unit
    
    def initialize(amount, unit)
      @amount, @unit = Rational(amount), Unit.parse(unit)
    end

    def <=>(other)
      check_compatibility!(other)
      
      amount <=> other.amount
    end

    def -@
      self.class.new(-amount, unit)
    end

    def +(other)
      check_compatibility!(other)

      self.class.new(amount + other.amount, unit)
    end

    def -(other)
      self + (-other)
    end

    def *(other)
      case other
      when Numeric
        self.class.new(amount * other, unit)
      when self.class
        self.class.new(amount * other.amount, unit * other.unit)
      else
        fail ArgumentError, "Can't multiply by #{other.class}"
      end
    end

    def /(other)
      case other
      when Numeric
        self.class.new(amount / other, unit)
      when self.class
        un = unit / other.unit
        un.scalar? ?
          amount / other.amount :
          self.class.new(amount / other.amount, un)
      else
        fail ArgumentError, "Can't divide by #{other.class}"
      end
    end

    def **(num)
      (num-1).times.inject(self){|res| res*self}
    end

    include Comparable

    def to_s
      '%s%s' % [formatted_amount, unit]
    end

    def inspect
      "#<%s(%s %s)>" % [self.class, formatted_amount, unit]
    end

    private

    def formatted_amount
      # FIXME: really naive
      if amount.abs < 1
        amount.to_f.to_s
      else
        # see http://stackoverflow.com/a/6460145/3683228
        amount.to_i.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
      end
    end

    def check_compatibility!(other)
      unless other.kind_of?(self.class) && other.unit == unit
        fail ArgumentError, "#{self} incompatible with #{other}"
      end
    end
  end

  def Reality.Measure(*arg)
    Measure.new(*arg)
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
reality-0.0.2 lib/reality/measure.rb
reality-0.0.1 lib/reality/measure.rb