Module: Money::Arithmetic
- Included in:
- Money
- Defined in:
- lib/money/money/arithmetic.rb
Defined Under Namespace
Classes: CoercedNumeric
Instance Method Summary collapse
-
#%(val) ⇒ Money
Synonym for
#modulo
. -
#*(value) ⇒ Money
Multiplies the monetary value with the given number and returns a new
Money
object with this monetary value and the same currency. -
#+(other) ⇒ Money
Returns a new Money object containing the sum of the two operands’ monetary values.
-
#-(other) ⇒ Money
Returns a new Money object containing the sum of the two operands’ monetary values.
-
#-@ ⇒ Money
Returns a money object with changed polarity.
-
#/(value) ⇒ Money, Float
Divides the monetary value with the given number and returns a new
Money
object with this monetary value and the same currency. -
#<=>(other) ⇒ Integer
Compares two Money objects.
-
#==(other) ⇒ Object
Uses Comparable’s implementation but raises ArgumentError if non-zero numeric value is given.
-
#abs ⇒ Money
Return absolute value of self as a new Money object.
-
#coerce(other) ⇒ Array
Used to make Money instance handle the operations when arguments order is reversed.
-
#div(value) ⇒ Money, Float
Synonym for
#/
. -
#divmod(val) ⇒ Array<Money,Money>, Array<Integer,Money>
Divide money by money or fixnum and return array containing quotient and modulus.
-
#eql?(other_money) ⇒ Boolean
Checks whether two Money objects have the same currency and the same amount.
-
#modulo(val) ⇒ Money
Equivalent to self.divmod(val).
-
#negative? ⇒ Boolean
Test if the amount is negative.
-
#nonzero? ⇒ Money?
Test if the money amount is non-zero.
-
#positive? ⇒ Boolean
Test if the amount is positive.
-
#remainder(val) ⇒ Money
If different signs self.modulo(val) - val otherwise self.modulo(val).
-
#zero? ⇒ Boolean
Test if the money amount is zero.
Instance Method Details
#%(val) ⇒ Money
Synonym for #modulo
.
264 265 266 |
# File 'lib/money/money/arithmetic.rb', line 264 def %(val) modulo(val) end |
#*(value) ⇒ Money
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.
167 168 169 170 171 172 173 174 |
# File 'lib/money/money/arithmetic.rb', line 167 def *(value) value = value.value if value.is_a?(CoercedNumeric) if value.is_a? Numeric dup_with(fractional: fractional * value) else raise TypeError, "Can't multiply a #{self.class.name} by a #{value.class.name}'s value" end end |
#+(other) ⇒ Money
Returns a new Money object containing the sum of the two operands’ monetary values. If other_money
has a different currency then its monetary value is automatically exchanged to this object’s currency using exchange_to
.
Returns a new Money object containing the difference between the two operands’ monetary values. If other_money
has a different currency then its monetary value is automatically exchanged to this object’s currency using exchange_to
.
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/money/money/arithmetic.rb', line 130 [:+, :-].each do |op| = lambda do |value| "Can't add or subtract a non-zero #{value.class.name} value" end define_method(op) do |other| case other when Money other = other.exchange_to(currency) new_fractional = fractional.public_send(op, other.fractional) dup_with(fractional: new_fractional) when CoercedNumeric raise TypeError, .call(other.value) unless other.zero? dup_with(fractional: other.value.public_send(op, fractional)) when Numeric raise TypeError, .call(other) unless other.zero? self else raise TypeError, "Unsupported argument type: #{other.class.name}" end end end |
#-(other) ⇒ Money
Returns a new Money object containing the sum of the two operands’ monetary values. If other_money
has a different currency then its monetary value is automatically exchanged to this object’s currency using exchange_to
.
Returns a new Money object containing the difference between the two operands’ monetary values. If other_money
has a different currency then its monetary value is automatically exchanged to this object’s currency using exchange_to
.
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/money/money/arithmetic.rb', line 130 [:+, :-].each do |op| = lambda do |value| "Can't add or subtract a non-zero #{value.class.name} value" end define_method(op) do |other| case other when Money other = other.exchange_to(currency) new_fractional = fractional.public_send(op, other.fractional) dup_with(fractional: new_fractional) when CoercedNumeric raise TypeError, .call(other.value) unless other.zero? dup_with(fractional: other.value.public_send(op, fractional)) when Numeric raise TypeError, .call(other) unless other.zero? self else raise TypeError, "Unsupported argument type: #{other.class.name}" end end end |
#-@ ⇒ Money
Returns a money object with changed polarity.
18 19 20 |
# File 'lib/money/money/arithmetic.rb', line 18 def -@ dup_with(fractional: -fractional) end |
#/(value) ⇒ Money, Float
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
.
191 192 193 194 195 196 197 198 |
# File 'lib/money/money/arithmetic.rb', line 191 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) dup_with(fractional: fractional / as_d(value)) end end |
#<=>(other) ⇒ Integer
Compares two Money objects. If money objects have a different currency it will attempt to convert the currency.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# 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 # Always allow comparison with zero if zero? || other.zero? return fractional <=> other.fractional end other = other.exchange_to(currency) fractional <=> other.fractional rescue Money::Bank::UnknownRate end |
#==(other) ⇒ Object
Uses Comparable’s implementation but raises ArgumentError if non-zero numeric value is given.
73 74 75 76 77 78 |
# File 'lib/money/money/arithmetic.rb', line 73 def ==(other) if other.is_a?(Numeric) && !other.zero? raise ArgumentError, 'Money#== supports only zero numerics' end super end |
#abs ⇒ Money
Return absolute value of self as a new Money object.
294 295 296 |
# File 'lib/money/money/arithmetic.rb', line 294 def abs dup_with(fractional: fractional.abs) end |
#coerce(other) ⇒ Array
Used to make Money instance handle the operations when arguments order is reversed
326 327 328 |
# File 'lib/money/money/arithmetic.rb', line 326 def coerce(other) [self, CoercedNumeric.new(other)] end |
#div(value) ⇒ Money, Float
Synonym for #/
.
209 210 211 |
# File 'lib/money/money/arithmetic.rb', line 209 def div(value) self / value end |
#divmod(val) ⇒ Array<Money,Money>, Array<Integer,Money>
Divide money by money or fixnum and return array containing quotient and modulus.
223 224 225 226 227 228 229 |
# File 'lib/money/money/arithmetic.rb', line 223 def divmod(val) if val.is_a?(Money) divmod_money(val) else divmod_other(val) end end |
#eql?(other_money) ⇒ Boolean
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.
37 38 39 40 41 42 43 44 |
# 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) ⇒ Money
Equivalent to self.divmod(val)
253 254 255 |
# File 'lib/money/money/arithmetic.rb', line 253 def modulo(val) divmod(val)[1] end |
#negative? ⇒ Boolean
Test if the amount is negative. Returns true
if the money amount is less than 0, false
otherwise.
102 103 104 |
# File 'lib/money/money/arithmetic.rb', line 102 def negative? fractional < 0 end |
#nonzero? ⇒ Money?
Test if the money amount is non-zero. Returns this money object if it is non-zero, or nil otherwise, like Numeric#nonzero?.
317 318 319 |
# File 'lib/money/money/arithmetic.rb', line 317 def nonzero? fractional != 0 ? self : nil end |
#positive? ⇒ Boolean
Test if the amount is positive. Returns true
if the money amount is greater than 0, false
otherwise.
89 90 91 |
# File 'lib/money/money/arithmetic.rb', line 89 def positive? fractional > 0 end |
#remainder(val) ⇒ Money
If different signs self.modulo(val) - val otherwise self.modulo(val)
276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/money/money/arithmetic.rb', line 276 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 : dup_with(fractional: val)) end end |
#zero? ⇒ Boolean
Test if the money amount is zero.
305 306 307 |
# File 'lib/money/money/arithmetic.rb', line 305 def zero? fractional == 0 end |