Class: Money::Money

Inherits:
Object show all
Includes:
Comparable
Defined in:
lib/money/money.rb

Overview

Money::Money is the central place for working with monetary values. You can create a new Money instance by one of these methods:

Initializing with amount and currency:

m = Money::Money.new(1.99, "EUR")

Initializing with amount only. The default_currency will then be used:

m = Money::Money.new(1.99)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(amount, currency = nil, bank = nil) ⇒ Money

Returns a new instance of Money.

Raises:



27
28
29
30
31
32
# File 'lib/money/money.rb', line 27

def initialize(amount, currency = nil, bank = nil)
  @amount   = amount
  @currency = currency || self.class.default_currency
  @bank     = bank || self.class.default_bank
  raise UnknownCurrency unless CURRENCIES[@currency]
end

Instance Attribute Details

#amountObject (readonly)

Returns the value of attribute amount.



25
26
27
# File 'lib/money/money.rb', line 25

def amount
  @amount
end

#bankObject (readonly)

Returns the value of attribute bank.



25
26
27
# File 'lib/money/money.rb', line 25

def bank
  @bank
end

#currencyObject (readonly)

Returns the value of attribute currency.



25
26
27
# File 'lib/money/money.rb', line 25

def currency
  @currency
end

Class Method Details

.default_bankObject



34
35
36
# File 'lib/money/money.rb', line 34

def self.default_bank
  Thread.current[:money_default_bank] || MeplatoBank.instance
end

.default_bank=(bank) ⇒ Object



38
39
40
# File 'lib/money/money.rb', line 38

def self.default_bank=(bank)
  Thread.current[:money_default_bank] = bank
end

.default_currencyObject



42
43
44
# File 'lib/money/money.rb', line 42

def self.default_currency
  Thread.current[:money_default_currency] || "USD"
end

.default_currency=(currency) ⇒ Object



46
47
48
# File 'lib/money/money.rb', line 46

def self.default_currency=(currency)
  Thread.current[:money_default_currency] = currency
end

.default_localeObject



50
51
52
# File 'lib/money/money.rb', line 50

def self.default_locale
  Thread.current[:money_default_locale] || "en"
end

.default_locale=(locale) ⇒ Object



54
55
56
# File 'lib/money/money.rb', line 54

def self.default_locale=(locale)
  Thread.current[:money_default_locale] = locale
end

.parse(value, currency, options = {}) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/money/money.rb', line 135

def self.parse(value, currency, options = {})
  return Money.new(0, currency, options) if value.nil?
  opts = {
    :locale => default_locale,
    :bank => default_bank,
    :currency => currency || default_currency
  }.merge(options)
  format = FORMATS[opts[:locale]]
  # TODO there's a special case e.g. "($12,345,678.90)" that has to be converted to -12345678.90
  s = value.gsub(/[^0-9\-#{format[:decimal_sep]}]/, '')
  s.gsub!(format[:decimal_sep], '.')
  Money.new(s.to_f, opts[:currency], opts)
end

.same_currency?(source, target) ⇒ Boolean

Returns:

  • (Boolean)


131
132
133
# File 'lib/money/money.rb', line 131

def self.same_currency?(source, target)
  source.upcase == target.upcase
end

Instance Method Details

#+(other) ⇒ Object



86
87
88
89
90
91
92
# File 'lib/money/money.rb', line 86

def +(other)
  if self.class.same_currency?(@currency, other.currency)
    Money.new(@amount + other.amount, @currency)
  else
    Money.new(@amount + other.exchange_to(@currency).amount, @currency)
  end
end

#-(other) ⇒ Object



94
95
96
97
98
99
100
# File 'lib/money/money.rb', line 94

def -(other)
  if self.class.same_currency?(@currency, other.currency)
    Money.new(@amount - other.amount, @currency)
  else
    Money.new(@amount - other.exchange_to(@currency).amount, @currency)
  end
end

#<=>(other) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/money/money.rb', line 78

def <=>(other)
  if self.class.same_currency?(@currency, other.currency)
    @amount <=> other.amount
  else
    @amount <=> other.exchange_to(@currency).amount
  end
end

#==(other) ⇒ Object



74
75
76
# File 'lib/money/money.rb', line 74

def ==(other)
  self.amount == other.amount && self.class.same_currency?(self.currency, other.currency)
end

#as_euroObject



114
115
116
# File 'lib/money/money.rb', line 114

def as_euro
  self.exchange_to("EUR")
end

#exchange_to(target) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
# File 'lib/money/money.rb', line 102

def exchange_to(target)
  unless self.class.same_currency?(@currency, target)
    rate = self.bank.get_rate(@currency, target)
    if !rate
      raise UnknownRate, "No conversion from #{@currency} to #{target}"
    end
    Money.new(@amount * rate, target)
  else
    self
  end
end

#format(options = {}) ⇒ Object



118
119
120
121
122
123
124
125
# File 'lib/money/money.rb', line 118

def format(options = {})
  defaults = {
    :locale => self.class.default_locale,
    :bank => @bank,
    :currency => @currency
  }
  MoneyFormatter.new(self, defaults.merge(options)).to_s
end

#nan?Boolean

Returns:

  • (Boolean)


70
71
72
# File 'lib/money/money.rb', line 70

def nan?
  @amount.nil?
end

#negative?Boolean

Returns:

  • (Boolean)


62
63
64
# File 'lib/money/money.rb', line 62

def negative?
  @amount && @amount < 0
end

#positive?Boolean

Returns:

  • (Boolean)


58
59
60
# File 'lib/money/money.rb', line 58

def positive?
  @amount && @amount > 0
end

#to_s(options = {}) ⇒ Object



127
128
129
# File 'lib/money/money.rb', line 127

def to_s(options = {})
  self.format(options)
end

#zero?Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/money/money.rb', line 66

def zero?
  @amount && @amount == 0
end