module Money::Arithmetic

Constants

CoercedNumeric

Wrapper for coerced numeric values to distinguish when numeric was on the 1st place in operation.

Public Instance Methods

%(val) click to toggle source

Synonym for #modulo.

@param [Money, Integer] val Number take modulo with.

@return [Money]

@see modulo

# File lib/money/money/arithmetic.rb, line 249
def %(val)
  modulo(val)
end
*(value) click to toggle source

Multiplies the monetary value with the given number and returns a new Money object with this monetary value and the same currency.

Note that you can't multiply a Money object by an other Money object.

@param [Numeric] value Number to multiply by.

@return [Money] The resulting money.

@raise [TypeError] If value is NOT a number.

@example

Money.new(100) * 2 #=> #<Money @fractional=200>
# File lib/money/money/arithmetic.rb, line 152
def *(value)
  value = value.value if value.is_a?(CoercedNumeric)
  if value.is_a? Numeric
    self.class.new(fractional * value, currency, bank)
  else
    raise TypeError, "Can't multiply a #{self.class.name} by a #{value.class.name}'s value"
  end
end
-@() click to toggle source

Returns a money object with changed polarity.

@return [Money]

@example

- Money.new(100) #=> #<Money @fractional=-100>
# File lib/money/money/arithmetic.rb, line 18
def -@
  self.class.new(-fractional, currency, bank)
end
/(value) click to toggle source

Divides the monetary value with the given number and returns a new Money object with this monetary value and the same currency. Can also divide by another Money object to get a ratio.

Money/Numeric returns Money. Money/Money returns Float.

@param [Money, Numeric] value Number to divide by.

@return [Money] The resulting money if you divide Money by a number. @return [Float] The resulting number if you divide Money by a Money.

@example

Money.new(100) / 10            #=> #<Money @fractional=10>
Money.new(100) / Money.new(10) #=> 10.0
# File lib/money/money/arithmetic.rb, line 176
def /(value)
  if value.is_a?(self.class)
    fractional / as_d(value.exchange_to(currency).fractional).to_f
  else
    raise TypeError, 'Can not divide by Money' if value.is_a?(CoercedNumeric)
    self.class.new(fractional / as_d(value), currency, bank)
  end
end
<=>(other) click to toggle source

Compares two Money objects. If money objects have a different currency it will attempt to convert the currency.

@param [Money] other_money Value to compare with.

@return [Integer]

@raise [TypeError] when other object is not Money

# File lib/money/money/arithmetic.rb, line 55
def <=>(other)
  unless other.is_a?(Money)
    return unless other.respond_to?(:zero?) && other.zero?
    return other.is_a?(CoercedNumeric) ? 0 <=> fractional : fractional <=> 0
  end
  return 0 if zero? && other.zero?
  other = other.exchange_to(currency)
  fractional <=> other.fractional
rescue Money::Bank::UnknownRate
end
==(other) click to toggle source

Uses Comparable's implementation but raises ArgumentError if non-zero numeric value is given.

Calls superclass method
# File lib/money/money/arithmetic.rb, line 68
def ==(other)
  if other.is_a?(Numeric) && !other.zero?
    raise ArgumentError, 'Money#== supports only zero numerics'
  end
  super
end
abs() click to toggle source

Return absolute value of self as a new Money object.

@return [Money]

@example

Money.new(-100).abs #=> #<Money @fractional=100>
# File lib/money/money/arithmetic.rb, line 279
def abs
  self.class.new(fractional.abs, currency, bank)
end
coerce(other) click to toggle source

Used to make Money instance handle the operations when arguments order is reversed @return [Array]

@example

2 * Money.new(10) #=> #<Money @fractional=20>
# File lib/money/money/arithmetic.rb, line 311
def coerce(other)
  [self, CoercedNumeric.new(other)]
end
div(value) click to toggle source

Synonym for #/.

@param [Money, Numeric] value Number to divide by.

@return [Money] The resulting money if you divide Money by a number. @return [Float] The resulting number if you divide Money by a Money.

@see #/

# File lib/money/money/arithmetic.rb, line 194
def div(value)
  self / value
end
divmod(val) click to toggle source

Divide money by money or fixnum and return array containing quotient and modulus.

@param [Money, Integer] val Number to divmod by.

@return [Array<Money,Money>,Array<Integer,Money>]

@example

Money.new(100).divmod(9)            #=> [#<Money @fractional=11>, #<Money @fractional=1>]
Money.new(100).divmod(Money.new(9)) #=> [11, #<Money @fractional=1>]
# File lib/money/money/arithmetic.rb, line 208
def divmod(val)
  if val.is_a?(Money)
    divmod_money(val)
  else
    divmod_other(val)
  end
end
eql?(other_money) click to toggle source

Checks whether two Money objects have the same currency and the same amount. If Money objects have a different currency it will only be true if the amounts are both zero. Checks against objects that are not Money or a subclass will always return false.

@param [Money] other_money Value to compare with.

@return [Boolean]

@example

Money.new(100).eql?(Money.new(101))                #=> false
Money.new(100).eql?(Money.new(100))                #=> true
Money.new(100, "USD").eql?(Money.new(100, "GBP"))  #=> false
Money.new(0, "USD").eql?(Money.new(0, "EUR"))      #=> true
Money.new(100).eql?("1.00")                        #=> false
# File lib/money/money/arithmetic.rb, line 37
def eql?(other_money)
  if other_money.is_a?(Money)
    (fractional == other_money.fractional && currency == other_money.currency) ||
      (fractional == 0 && other_money.fractional == 0)
  else
    false
  end
end
modulo(val) click to toggle source

Equivalent to +self.divmod(val)+

@param [Money, Integer] val Number take modulo with.

@return [Money]

@example

Money.new(100).modulo(9)            #=> #<Money @fractional=1>
Money.new(100).modulo(Money.new(9)) #=> #<Money @fractional=1>
# File lib/money/money/arithmetic.rb, line 238
def modulo(val)
  divmod(val)[1]
end
negative?() click to toggle source

Test if the amount is negative. Returns true if the money amount is less than 0, false otherwise.

@return [Boolean]

@example

Money.new(-1).negative? #=> true
Money.new(0).negative?  #=> false
Money.new(1).negative?  #=> false
# File lib/money/money/arithmetic.rb, line 97
def negative?
  fractional < 0
end
nonzero?() click to toggle source

Test if the money amount is non-zero. Returns this money object if it is non-zero, or nil otherwise, like +Numeric#nonzero?+.

@return [Money, nil]

@example

Money.new(100).nonzero? #=> #<Money @fractional=100>
Money.new(0).nonzero?   #=> nil
# File lib/money/money/arithmetic.rb, line 302
def nonzero?
  fractional != 0 ? self : nil
end
positive?() click to toggle source

Test if the amount is positive. Returns true if the money amount is greater than 0, false otherwise.

@return [Boolean]

@example

Money.new(1).positive?  #=> true
Money.new(0).positive?  #=> false
Money.new(-1).positive? #=> false
# File lib/money/money/arithmetic.rb, line 84
def positive?
  fractional > 0
end
remainder(val) click to toggle source

If different signs +self.modulo(val) - val+ otherwise +self.modulo(val)+

@param [Money, Integer] val Number to rake remainder with.

@return [Money]

@example

Money.new(100).remainder(9) #=> #<Money @fractional=1>
# File lib/money/money/arithmetic.rb, line 261
def remainder(val)
  if val.is_a?(Money) && currency != val.currency
    val = val.exchange_to(currency)
  end

  if (fractional < 0 && val < 0) || (fractional > 0 && val > 0)
    self.modulo(val)
  else
    self.modulo(val) - (val.is_a?(Money) ? val : self.class.new(val, currency, bank))
  end
end
zero?() click to toggle source

Test if the money amount is zero.

@return [Boolean]

@example

Money.new(100).zero? #=> false
Money.new(0).zero?   #=> true
# File lib/money/money/arithmetic.rb, line 290
def zero?
  fractional == 0
end

Private Instance Methods

divmod_money(val) click to toggle source
# File lib/money/money/arithmetic.rb, line 216
def divmod_money(val)
  cents = val.exchange_to(currency).cents
  quotient, remainder = fractional.divmod(cents)
  [quotient, self.class.new(remainder, currency, bank)]
end
divmod_other(val) click to toggle source
# File lib/money/money/arithmetic.rb, line 223
def divmod_other(val)
  quotient, remainder = fractional.divmod(as_d(val))
  [self.class.new(quotient, currency, bank), self.class.new(remainder, currency, bank)]
end