Module: Amount::Arithmetic

Included in:
Amount
Defined in:
lib/amount/arithmetic.rb

Overview

Arithmetic operators for ‘Amount`. Mixed into `Amount` and inherited by any registered subclass.

All operators preserve the receiver’s class via ‘build`, so subclass identity (`GoldAmount`) survives through `+`, `-`, `*`, `/`, `abs`, `-@`.

Instance Method Summary collapse

Instance Method Details

#*(scalar) ⇒ Amount

Examples:

Amount.usdc("1.25") * 2

Parameters:

  • scalar (Numeric)

Returns:

Raises:



55
56
57
58
# File 'lib/amount/arithmetic.rb', line 55

def *(scalar)
  ensure_scalar!(scalar)
  build((BigDecimal(@atomic) * Amount.coerce_decimal(scalar)).to_i)
end

#+(other) ⇒ Amount

Examples:

Same-type addition

Amount.usdc("1.50") + Amount.usdc("0.50")

Cross-type addition using a registered directional rate

Amount.register_default_rate :USD, :USDC, "1"
Amount.usdc("10.00") + Amount.new("5.00", :USD)

Parameters:

Returns:

Raises:



35
36
37
38
# File 'lib/amount/arithmetic.rb', line 35

def +(other)
  rhs = coerce_other_to_self_type!(other)
  build(@atomic + rhs.atomic)
end

#-(other) ⇒ Amount

Examples:

Amount.usdc("2.00") - Amount.usdc("0.50")

Parameters:

Returns:

Raises:



45
46
47
48
# File 'lib/amount/arithmetic.rb', line 45

def -(other)
  rhs = coerce_other_to_self_type!(other)
  build(@atomic - rhs.atomic)
end

#-@Amount

Examples:

-Amount.usdc("1")
# => #<Amount USDC -$1.00>

Returns:



22
23
24
# File 'lib/amount/arithmetic.rb', line 22

def -@
  build(-@atomic)
end

#/(other) ⇒ Amount, BigDecimal

Examples:

Dividing by a scalar returns an amount

Amount.usdc("1.00") / 2

Dividing by an amount returns a ratio

Amount.usdc("10.00") / Amount.usdc("2.00")

Parameters:

Returns:

Raises:



68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/amount/arithmetic.rb', line 68

def /(other)
  if other.is_a?(Amount)
    ensure_same_type!(other)
    raise ZeroDivisionError if other.zero?

    BigDecimal(@atomic) / BigDecimal(other.atomic)
  else
    ensure_scalar!(other)
    raise ZeroDivisionError if other.zero?

    build((BigDecimal(@atomic) / Amount.coerce_decimal(other)).to_i)
  end
end

#absAmount

Examples:

Amount.usdc("-1").abs
# => #<Amount USDC $1.00>

Returns:



14
15
16
# File 'lib/amount/arithmetic.rb', line 14

def abs
  build(@atomic.abs)
end