module Money::Arithmetic
Constants
- CoercedNumeric
Wrapper for coerced numeric values to distinguish when numeric was on the 1st place in operation.
Public Instance Methods
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
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
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
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
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
Uses Comparable's implementation but raises ArgumentError if non-zero numeric value is given.
# 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
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
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
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
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
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
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
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
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
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
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
# 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
# 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