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 difference between 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)[1]+.
-
#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+.
280 281 282 |
# File 'lib/money/money/arithmetic.rb', line 280 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.
175 176 177 178 179 180 181 182 |
# File 'lib/money/money/arithmetic.rb', line 175 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+.
|
|
# File 'lib/money/money/arithmetic.rb', line 116
|
#-(other) ⇒ Money
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+.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/money/money/arithmetic.rb', line 138 [:+, :-].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.
20 21 22 |
# File 'lib/money/money/arithmetic.rb', line 20 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+.
199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/money/money/arithmetic.rb', line 199 def /(value) if value.is_a?(self.class) exchanged = value.exchange_to(currency) raise ZeroDivisionError, "divided by Money(0)" if exchanged.zero? fractional / as_d(exchanged.fractional).to_f else raise TypeError, 'Can not divide by Money' if value.is_a?(CoercedNumeric) value = as_d(value) raise ZeroDivisionError, "divided by zero" if value.zero? dup_with(fractional: fractional / value) end end |
#<=>(other) ⇒ Integer
Compares two Money objects. If money objects have a different currency it will attempt to convert the currency.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/money/money/arithmetic.rb', line 65 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.
83 84 85 86 87 88 |
# File 'lib/money/money/arithmetic.rb', line 83 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.
310 311 312 |
# File 'lib/money/money/arithmetic.rb', line 310 def abs dup_with(fractional: fractional.abs) end |
#coerce(other) ⇒ Array
Used to make Money instance handle the operations when arguments order is reversed
342 343 344 |
# File 'lib/money/money/arithmetic.rb', line 342 def coerce(other) [self, CoercedNumeric.new(other)] end |
#div(value) ⇒ Money, Float
Synonym for +#/+.
222 223 224 |
# File 'lib/money/money/arithmetic.rb', line 222 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.
236 237 238 239 240 241 242 |
# File 'lib/money/money/arithmetic.rb', line 236 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. Checks against objects that are not Money or a subclass will always return false.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/money/money/arithmetic.rb', line 40 def eql?(other_money) if other_money.is_a?(Money) if !Money.strict_eql_compare && fractional == 0 && other_money.fractional == 0 warn "[DEPRECATION] Comparing 0 #{currency} with 0 " \ "#{other_money.currency} using `#eql?` will return false in " \ "future versions of Money. Opt-in to the new behavior by " \ "setting `Money.strict_eql_compare = true`." return true end fractional == other_money.fractional && currency == other_money.currency else false end end |
#modulo(val) ⇒ Money
Equivalent to +self.divmod(val)[1]+
269 270 271 |
# File 'lib/money/money/arithmetic.rb', line 269 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.
112 113 114 |
# File 'lib/money/money/arithmetic.rb', line 112 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?+.
333 334 335 |
# File 'lib/money/money/arithmetic.rb', line 333 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.
99 100 101 |
# File 'lib/money/money/arithmetic.rb', line 99 def positive? fractional > 0 end |
#remainder(val) ⇒ Money
If different signs +self.modulo(val) - val+ otherwise +self.modulo(val)+
292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/money/money/arithmetic.rb', line 292 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.
321 322 323 |
# File 'lib/money/money/arithmetic.rb', line 321 def zero? fractional == 0 end |