Class: Money

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/money/money.rb,
lib/money/errors.rb,
lib/money/variable_exchange_bank.rb

Overview

Class for aiding in exchanging money between different currencies. By default, the Money class uses an object of this class (accessible through Money#bank) for performing currency exchanges.

By default, VariableExchangeBank has no knowledge about conversion rates. One must manually specify them with add_rate, after which one can perform exchanges with exchange. For example:

bank = Money::VariableExchangeBank.new
bank.add_rate("USD", "CAD", 1.24515)
bank.add_rate("CAD", "USD", 0.803115)

# Exchange 100 CAD to USD:
bank.exchange(100_00, "CAD", "USD")  # => 124
# Exchange 100 USD to CAD:
bank.exchange(100_00, "USD", "CAD")  # => 80

Defined Under Namespace

Classes: UnknownRate, VariableExchangeBank

Constant Summary collapse

SYMBOLS =

Add more from www.xe.com/symbols.php

{
  "GBP" => "£",
  "JPY" => "¥",
  "EUR" => "",
  "ZWD" => "Z$",
  "CNY" => "¥",
  "INR" => "",
  "NPR" => "",
  "SCR" => "",
  "LKR" => "",
  "SEK" => "kr",
  "GHC" => "¢"
  
  # Everything else defaults to $
}

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cents, currency = Money.default_currency, bank = Money.default_bank) ⇒ Money

Creates a new money object.

Money.new(100)

Alternativly you can use the convinience methods like Money.ca_dollar and Money.us_dollar



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

def initialize(cents, currency = Money.default_currency, bank = Money.default_bank)
  @cents = cents.round
  @currency = currency
  @bank = bank
end

Class Attribute Details

.default_bankObject

Each Money object is associated to a bank object, which is responsible for currency exchange. This property allows one to specify the default bank object.

bank1 = MyBank.new
bank2 = MyOtherBank.new

Money.default_bank = bank1
money1 = Money.new(10)
money1.bank  # => bank1

Money.default_bank = bank2
money2 = Money.new(10)
money2.bank  # => bank2
money1.bank  # => bank1

The default value for this property is an instance if VariableExchangeBank. It allows one to specify custom exchange rates:

Money.default_bank.add_rate("USD", "CAD", 1.24515)
Money.default_bank.add_rate("CAD", "USD", 0.803115)
Money.us_dollar(100).exchange_to("CAD")  # => Money.ca_dollar(124)
Money.ca_dollar(100).exchange_to("USD")  # => Money.us_dollar(80)


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

def default_bank
  @default_bank
end

.default_currencyObject

The default currency, which is used when Money.new is called without an explicit currency argument. The default value is “USD”.



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

def default_currency
  @default_currency
end

Instance Attribute Details

#bankObject (readonly)

Returns the value of attribute bank.



7
8
9
# File 'lib/money/money.rb', line 7

def bank
  @bank
end

#centsObject (readonly)

get the cents value of the object



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

def cents
  @cents
end

#currencyObject (readonly)

Returns the value of attribute currency.



7
8
9
# File 'lib/money/money.rb', line 7

def currency
  @currency
end

Class Method Details

.add_rate(from_currency, to_currency, rate) ⇒ Object



64
65
66
# File 'lib/money/money.rb', line 64

def self.add_rate(from_currency, to_currency, rate)
  Money.default_bank.add_rate(from_currency, to_currency, rate)
end

.ca_dollar(cents) ⇒ Object

Creates a new Money object of the given value, using the Canadian dollar currency.



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

def self.ca_dollar(cents)
  Money.new(cents, "CAD")
end

.empty(currency = default_currency) ⇒ Object

Create a new money object with value 0.



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

def self.empty(currency = default_currency)
  Money.new(0, currency)
end

.euro(cents) ⇒ Object

Creates a new Money object of the given value, using the Euro currency.



60
61
62
# File 'lib/money/money.rb', line 60

def self.euro(cents)
  Money.new(cents, "EUR")
end

.us_dollar(cents) ⇒ Object

Creates a new Money object of the given value, using the American dollar currency.



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

def self.us_dollar(cents)
  Money.new(cents, "USD")
end

Instance Method Details

#*(fixnum) ⇒ Object

multiply money by fixnum



119
120
121
# File 'lib/money/money.rb', line 119

def *(fixnum)
  Money.new(cents * fixnum, currency)
end

#+(other_money) ⇒ Object



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

def +(other_money)
  other_money = other_money.to_money
  if currency == other_money.currency
    Money.new(cents + other_money.cents, other_money.currency)
  else
    Money.new(cents + other_money.exchange_to(currency).cents,currency)
  end
end

#-(other_money) ⇒ Object



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

def -(other_money)
  other_money = other_money.to_money
  if currency == other_money.currency
    Money.new(cents - other_money.cents, other_money.currency)
  else
    Money.new(cents - other_money.exchange_to(currency).cents, currency)
  end
end

#/(fixnum) ⇒ Object

divide money by fixnum



124
125
126
# File 'lib/money/money.rb', line 124

def /(fixnum)
  Money.new(cents / fixnum, currency)
end

#<=>(other_money) ⇒ Object



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

def <=>(other_money)
  other_money = other_money.to_money
  if bank.same_currency?(currency, other_money.currency)
    cents <=> other_money.cents
  else
    cents <=> other_money.exchange_to(currency).cents
  end
end

#==(other_money) ⇒ Object

Do two money objects equal? Only works if both objects are of the same currency



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

def ==(other_money)
  other_money = other_money.to_money
  cents == other_money.cents && bank.same_currency?(currency, other_money.currency)
end

#as_ca_dollarObject

Recieve a money object with the same amount as the current Money object in canadian dollar



262
263
264
# File 'lib/money/money.rb', line 262

def as_ca_dollar
  exchange_to("CAD")
end

#as_euroObject

Recieve a money object with the same amount as the current Money object in euro



268
269
270
# File 'lib/money/money.rb', line 268

def as_euro
  exchange_to("EUR")
end

#as_us_dollarObject

Recieve a money object with the same amount as the current Money object in american dollar



256
257
258
# File 'lib/money/money.rb', line 256

def as_us_dollar
  exchange_to("USD")
end

#exchange_to(other_currency) ⇒ Object

Recieve the amount of this money object in another currency.



250
251
252
# File 'lib/money/money.rb', line 250

def exchange_to(other_currency)
  Money.new(@bank.exchange(self.cents, currency, other_currency), other_currency)
end

#format(*rules) ⇒ Object

Creates a formatted price string according to several rules. The following options are supported: :display_free, :with_currency, :no_cents, :symbol and :html.

:display_free

Whether a zero amount of money should be formatted of “free” or as the supplied string.

Money.us_dollar(0).format(:display_free => true)      => "free"
Money.us_dollar(0).format(:display_free => "gratis")  => "gratis"
Money.us_dollar(0).format => "$0.00"

:with_currency

Whether the currency name should be appended to the result string.

Money.ca_dollar(100).format => "$1.00"
Money.ca_dollar(100).format(:with_currency => true) => "$1.00 CAD"
Money.us_dollar(85).format(:with_currency => true)  => "$0.85 USD"

:no_cents

Whether cents should be omitted.

Money.ca_dollar(100).format(:no_cents => true) => "$1"
Money.ca_dollar(599).format(:no_cents => true) => "$5"

Money.ca_dollar(570).format(:no_cents => true, :with_currency => true) => "$5 CAD"
Money.ca_dollar(39000).format(:no_cents => true) => "$390"

:symbol

Whether a money symbol should be prepended to the result string. The default is true. This method attempts to pick a symbol that’s suitable for the given currency.

Money.new(100, "USD")  => "$1.00"
Money.new(100, "GBP")  => "£1.00"
Money.new(100, "EUR")  => "€1.00"

# Same thing.
Money.new(100, "USD").format(:symbol => true)  => "$1.00"
Money.new(100, "GBP").format(:symbol => true)  => "£1.00"
Money.new(100, "EUR").format(:symbol => true)  => "€1.00"

You can specify a false expression or an empty string to disable prepending a money symbol:

Money.new(100, "USD").format(:symbol => false)  => "1.00"
Money.new(100, "GBP").format(:symbol => nil)    => "1.00"
Money.new(100, "EUR").format(:symbol => "")     => "1.00"

If the symbol for the given currency isn’t known, then it will default to “$” as symbol:

Money.new(100, "AWG").format(:symbol => true)  => "$1.00"

You can specify a string as value to enforce using a particular symbol:

Money.new(100, "AWG").format(:symbol => "ƒ")   => "ƒ1.00"

:html

Whether the currency should be HTML-formatted. Only useful in combination with :with_currency.

Money.ca_dollar(570).format(:html => true, :with_currency => true)
  =>  "$5.70 <span class=\"currency\">CAD</span>"


202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/money/money.rb', line 202

def format(*rules)
  # support for old format parameters
  rules = normalize_formatting_rules(rules)
  
  if cents == 0
    if rules[:display_free].respond_to?(:to_str)
      return rules[:display_free]
    elsif rules[:display_free]
      return "free"
    end
  end

  if !rules.has_key?(:symbol) || rules[:symbol] === true
      symbol = SYMBOLS[currency] || "$"
  elsif rules[:symbol]
    symbol = rules[:symbol]
  else
    symbol = ""
  end

  if rules[:no_cents]
    formatted = sprintf("#{symbol}%d", cents.to_f / 100)
  else
    formatted = sprintf("#{symbol}%.2f", cents.to_f / 100)
  end
  
  # Commify ("10000" => "10,000")
  unless rules[:no_commas]
    formatted.gsub!(/(\d)(?=\d{3}+(?:\.|$))(\d{3}\..*)?/,'\1,\2')
  end
  
  if rules[:with_currency]
    formatted << " "
    formatted << '<span class="currency">' if rules[:html]
    formatted << currency
    formatted << '</span>' if rules[:html]
  end
  formatted
end

#to_moneyObject

Conversation to self



273
274
275
# File 'lib/money/money.rb', line 273

def to_money
  self
end

#to_sObject

Returns the amount of money as a string.

Money.ca_dollar(100).to_s => "1.00"


245
246
247
# File 'lib/money/money.rb', line 245

def to_s
  sprintf("%.2f", cents / 100.00)
end

#zero?Boolean

Test if the money amount is zero

Returns:

  • (Boolean)


129
130
131
# File 'lib/money/money.rb', line 129

def zero?
  cents == 0
end