Module WhittakerTech::Midas::Coin::Arithmetic ¶
Arithmetic defines the arithmetic and equality semantics of a Coin.
Design invariants¶
- Immutable — all operations return new, frozen
Coinobjects. - Closed — operations always return a
Coin, never a primitive. - Policy-aware only where unavoidable — division accepts a rounding policy; all other operations are exact.
- Currency-strict — binary operations (
+,-,==) raiseArgumentErrorwhen the operands have different currency codes.
Convenience division helpers¶
For each key in WhittakerTech::Midas::ROUNDING_POLICIES a named
shorthand is generated:
coin.divide_round(3) # same as coin.divide(3, rounding_policy: :round)
coin.divide_ceil(3)
coin.divide_floor(3)
coin.divide_bankers(3)
- @since 0.1.0
Public Instance Methods¶
%(other) ¶
Returns the remainder after dividing by an integer.
- @param
other[Integer] the divisor - @raise [TypeError] if
otheris not an Integer - @raise [ZeroDivisionError] if
otheris zero - @return [Coin] a new, frozen Coin representing the remainder
- @since 0.1.0
@example
Coin.value(1001, 'USD') % 3 # => Coin($0.02) (1001 % 3 == 2 cents)
*(other) ¶
Multiplies the Coin by an integer scalar.
- @param
other[Integer] the multiplier - @raise [TypeError] if
otheris not an Integer - @return [Coin] a new, frozen Coin
- @since 0.1.0
@example
Coin.value(500, 'USD') * 3 # => Coin($15.00)
+(other) ¶
Adds two Coins and returns the sum as a new Coin.
- @param
other[Coin] must have the same currency code as the receiver - @raise [TypeError] if
otheris not aCoin - @raise [ArgumentError] if the currencies do not match
- @return [Coin] a new, frozen Coin
- @since 0.1.0
@example
a = Coin.value(1000, 'USD')
b = Coin.value(500, 'USD')
a + b # => Coin($15.00)
-(other) ¶
Subtracts another Coin from the receiver and returns the difference.
- @param
other[Coin] must have the same currency code as the receiver - @raise [TypeError] if
otheris not aCoin - @raise [ArgumentError] if the currencies do not match
- @return [Coin] a new, frozen Coin
- @since 0.1.0
@example
a = Coin.value(1000, 'USD')
b = Coin.value(300, 'USD')
a - b # => Coin($7.00)
-@() ¶
Unary minus operator — shorthand for #negate.
- @return [Coin]
- @since 0.1.0
==(other) ¶
Tests value equality with another Coin.
Two Coins are equal when they have the same currency code and the same minor-unit amount. A Coin is never equal to a non-Coin object.
- @param
other[Object] the object to compare - @return [Boolean]
- @since 0.1.0
divide(divisor, rounding_policy: = WhittakerTech::Midas::DEFAULT_ROUNDING_POLICY) ¶
Divides the Coin by a numeric divisor and returns the quotient.
Division is the only arithmetic operation that requires a rounding policy because dividing integer minor units can produce a non-integer result.
- @param
divisor[Numeric] the divisor; must be non-zero -
@param
rounding_policy[Symbol] one of the keys inWhittakerTech::Midas::ROUNDING_POLICIES(default:WhittakerTech::Midas::DEFAULT_ROUNDING_POLICY) -
@raise [TypeError] if
divisoris not Numeric - @raise [ZeroDivisionError] if
divisoris zero - @return [Coin] a new, frozen Coin
- @since 0.1.0
@example
Coin.value(1000, 'USD').divide(3, rounding_policy: :ceil) # => Coin($3.34)
Coin.value(1000, 'USD').divide(3, rounding_policy: :floor) # => Coin($3.33)
Coin.value(1000, 'USD').divide(3, rounding_policy: :bankers)# => Coin($3.33)
hash() ¶
Returns a hash value consistent with #eql?.
Coins with the same currency code and minor-unit amount produce the same hash, making them interchangeable as Hash keys or Set members.
- @return [Integer]
- @since 0.1.0
negate() ¶
Returns a new Coin with the sign reversed.
- @return [Coin] a new, frozen Coin
- @since 0.1.0
@example
Coin.value(500, 'USD').negate # => Coin(-$5.00)