Module: Money::Arithmetic

Included in:
Money
Defined in:
lib/money/money/arithmetic.rb

Defined Under Namespace

Classes: CoercedNumeric

Instance Method Summary collapse

• Synonym for `#modulo`.

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

• Returns a new Money object containing the sum of the two operands' monetary values.

• Returns a new Money object containing the sum of the two operands' monetary values.

• Returns a money object with changed polarity.

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

• Compares two Money objects.

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

• Return absolute value of self as a new Money object.

• Used to make Money instance handle the operations when arguments order is reversed.

• Synonym for `#/`.

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

• Checks whether two Money objects have the same currency and the same amount.

• Equivalent to self.divmod(val).

• Test if the amount is negative.

• Test if the money amount is non-zero.

• Test if the amount is positive.

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

• Test if the money amount is zero.

Instance Method Details

#%(val) ⇒ Money

Synonym for `#modulo`.

Parameters:

• val (Money, Integer)

Number take modulo with.

Returns:

 ``` 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.

Examples:

``Money.new(100) * 2 #=> #<Money @fractional=200>``

Parameters:

• value (Numeric)

Number to multiply by.

Returns:

• (Money)

The resulting money.

Raises:

• (TypeError)

If `value` is NOT a number.

 ``` 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`.

Examples:

``Money.new(100) + Money.new(100) #=> #<Money @fractional=200>``
``Money.new(100) - Money.new(99) #=> #<Money @fractional=1>``

Parameters:

• other (Money)

Other `Money` object to add.

• other (Money)

Other `Money` object to subtract.

Returns:

 ``` 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| non_zero_message = 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, non_zero_message.call(other.value) unless other.zero? dup_with(fractional: other.value.public_send(op, fractional)) when Numeric raise TypeError, non_zero_message.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`.

Examples:

``Money.new(100) + Money.new(100) #=> #<Money @fractional=200>``
``Money.new(100) - Money.new(99) #=> #<Money @fractional=1>``

Parameters:

• other (Money)

Other `Money` object to add.

• other (Money)

Other `Money` object to subtract.

Returns:

 ``` 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| non_zero_message = 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, non_zero_message.call(other.value) unless other.zero? dup_with(fractional: other.value.public_send(op, fractional)) when Numeric raise TypeError, non_zero_message.call(other) unless other.zero? self else raise TypeError, "Unsupported argument type: #{other.class.name}" end end end```

#[email protected] ⇒ Money

Returns a money object with changed polarity.

Examples:

``- Money.new(100) #=> #<Money @fractional=-100>``

Returns:

 ``` 18 19 20``` ```# File 'lib/money/money/arithmetic.rb', line 18 def [email protected] 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`.

Examples:

``````Money.new(100) / 10            #=> #<Money @fractional=10>
Money.new(100) / Money.new(10) #=> 10.0``````

Parameters:

• value (Money, Numeric)

Number to divide by.

Returns:

• (Money)

The resulting money if you divide Money by a number.

• (Float)

The resulting number if you divide Money by a Money.

 ``` 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.

Parameters:

• other (Money)

Value to compare with.

Returns:

• (Integer)

Raises:

• (TypeError)

when other object is not Money

 ``` 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.

Examples:

``Money.new(-100).abs #=> #<Money @fractional=100>``

Returns:

 ``` 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

Examples:

``2 * Money.new(10) #=> #<Money @fractional=20>``

Returns:

• (Array)
 ``` 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 `#/`.

Parameters:

• value (Money, Numeric)

Number to divide by.

Returns:

• (Money)

The resulting money if you divide Money by a number.

• (Float)

The resulting number if you divide Money by a Money.

 ``` 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.

Examples:

``````Money.new(100).divmod(9)            #=> [#<Money @fractional=11>, #<Money @fractional=1>]
Money.new(100).divmod(Money.new(9)) #=> [11, #<Money @fractional=1>]``````

Parameters:

• val (Money, Integer)

Number to divmod by.

Returns:

 ``` 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.

Examples:

``````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``````

Parameters:

• other_money (Money)

Value to compare with.

Returns:

• (Boolean)
 ``` 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)

Examples:

``````Money.new(100).modulo(9)            #=> #<Money @fractional=1>
Money.new(100).modulo(Money.new(9)) #=> #<Money @fractional=1>``````

Parameters:

• val (Money, Integer)

Number take modulo with.

Returns:

 ``` 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.

Examples:

``````Money.new(-1).negative? #=> true
Money.new(0).negative?  #=> false
Money.new(1).negative?  #=> false``````

Returns:

• (Boolean)
 ``` 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?.

Examples:

``````Money.new(100).nonzero? #=> #<Money @fractional=100>
Money.new(0).nonzero?   #=> nil``````

Returns:

 ``` 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.

Examples:

``````Money.new(1).positive?  #=> true
Money.new(0).positive?  #=> false
Money.new(-1).positive? #=> false``````

Returns:

• (Boolean)
 ``` 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)

Examples:

``Money.new(100).remainder(9) #=> #<Money @fractional=1>``

Parameters:

• val (Money, Integer)

Number to rake remainder with.

Returns:

 ``` 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.

Examples:

``````Money.new(100).zero? #=> false
Money.new(0).zero?   #=> true``````

Returns:

• (Boolean)
 ``` 305 306 307``` ```# File 'lib/money/money/arithmetic.rb', line 305 def zero? fractional == 0 end```