money 2.1.5 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,19 +1,31 @@
1
- # encoding: utf-8
2
-
3
- # Add more from http://www.xe.com/symbols.php
4
- Money::SYMBOLS = {
5
- "GBP" => "£",
6
- "JPY" => "¥",
7
- "EUR" => "€",
8
- "ZWD" => "Z$",
9
- "CNY" => "¥",
10
- "INR" => "₨",
11
- "NPR" => "₨",
12
- "SCR" => "₨",
13
- "LKR" => "₨",
14
- "SEK" => "kr",
15
- "GHC" => "¢",
16
- "BRL" => "R$"
17
-
18
- # Everything else defaults to $
19
- }
1
+ # encoding: utf-8
2
+
3
+ # Add more from http://www.xe.com/symbols.php
4
+ Money::SYMBOLS = {
5
+ "GBP" => "£",
6
+ "JPY" => "¥",
7
+ "EUR" => "€",
8
+ "ZWD" => "Z$",
9
+ "CNY" => "¥",
10
+ "INR" => "₨",
11
+ "NPR" => "₨",
12
+ "SCR" => "₨",
13
+ "LKR" => "₨",
14
+ "SEK" => "kr",
15
+ "GHC" => "¢",
16
+ "BRL" => "R$ ",
17
+
18
+ # Everything else defaults to '$'
19
+ }
20
+
21
+ Money::SEPARATORS = {
22
+ "BRL" => ",",
23
+
24
+ # Everything else defaults to '.'
25
+ }
26
+
27
+ Money::DELIMITERS = {
28
+ "BRL" => ".",
29
+
30
+ # Everything else defaults to ","
31
+ }
@@ -1,4 +1,4 @@
1
- class Money
2
- class UnknownRate < StandardError
3
- end
4
- end
1
+ class Money
2
+ class UnknownRate < StandardError
3
+ end
4
+ end
@@ -1,299 +1,388 @@
1
- require 'money/variable_exchange_bank'
2
-
3
- # Represents an amount of money in a certain currency.
4
- class Money
5
- include Comparable
6
-
7
- attr_reader :cents, :currency, :bank
8
-
9
- class << self
10
- # Each Money object is associated to a bank object, which is responsible
11
- # for currency exchange. This property allows one to specify the default
12
- # bank object.
13
- #
14
- # bank1 = MyBank.new
15
- # bank2 = MyOtherBank.new
16
- #
17
- # Money.default_bank = bank1
18
- # money1 = Money.new(10)
19
- # money1.bank # => bank1
20
- #
21
- # Money.default_bank = bank2
22
- # money2 = Money.new(10)
23
- # money2.bank # => bank2
24
- # money1.bank # => bank1
25
- #
26
- # The default value for this property is an instance if VariableExchangeBank.
27
- # It allows one to specify custom exchange rates:
28
- #
29
- # Money.default_bank.add_rate("USD", "CAD", 1.24515)
30
- # Money.default_bank.add_rate("CAD", "USD", 0.803115)
31
- # Money.us_dollar(100).exchange_to("CAD") # => Money.ca_dollar(124)
32
- # Money.ca_dollar(100).exchange_to("USD") # => Money.us_dollar(80)
33
- attr_accessor :default_bank
34
-
35
- # The default currency, which is used when <tt>Money.new</tt> is called
36
- # without an explicit currency argument. The default value is "USD".
37
- attr_accessor :default_currency
38
- end
39
-
40
- self.default_bank = VariableExchangeBank.instance
41
- self.default_currency = "USD"
42
-
43
-
44
- # Create a new money object with value 0.
45
- def self.empty(currency = default_currency)
46
- Money.new(0, currency)
47
- end
48
-
49
- # Creates a new Money object of the given value, using the Canadian dollar currency.
50
- def self.ca_dollar(cents)
51
- Money.new(cents, "CAD")
52
- end
53
-
54
- # Creates a new Money object of the given value, using the American dollar currency.
55
- def self.us_dollar(cents)
56
- Money.new(cents, "USD")
57
- end
58
-
59
- # Creates a new Money object of the given value, using the Euro currency.
60
- def self.euro(cents)
61
- Money.new(cents, "EUR")
62
- end
63
-
64
- def self.add_rate(from_currency, to_currency, rate)
65
- Money.default_bank.add_rate(from_currency, to_currency, rate)
66
- end
67
-
68
-
69
- # Creates a new money object.
70
- # Money.new(100)
71
- #
72
- # Alternativly you can use the convinience methods like
73
- # Money.ca_dollar and Money.us_dollar
74
- def initialize(cents, currency = Money.default_currency, bank = Money.default_bank)
75
- @cents = cents.round
76
- if currency.is_a?(Hash)
77
- # Earlier versions of Money wrongly documented the constructor as being able
78
- # to accept something like this:
79
- #
80
- # Money.new(50, :currency => "USD")
81
- #
82
- # We retain compatibility here.
83
- @currency = currency[:currency] || Money.default_currency
84
- else
85
- @currency = currency
86
- end
87
- @bank = bank
88
- end
89
-
90
- # Do two money objects equal? Only works if both objects are of the same currency
91
- def ==(other_money)
92
- cents == other_money.cents && bank.same_currency?(currency, other_money.currency)
93
- end
94
-
95
- def <=>(other_money)
96
- if bank.same_currency?(currency, other_money.currency)
97
- cents <=> other_money.cents
98
- else
99
- cents <=> other_money.exchange_to(currency).cents
100
- end
101
- end
102
-
103
- def +(other_money)
104
- if currency == other_money.currency
105
- Money.new(cents + other_money.cents, other_money.currency)
106
- else
107
- Money.new(cents + other_money.exchange_to(currency).cents, currency)
108
- end
109
- end
110
-
111
- def -(other_money)
112
- if currency == other_money.currency
113
- Money.new(cents - other_money.cents, other_money.currency)
114
- else
115
- Money.new(cents - other_money.exchange_to(currency).cents, currency)
116
- end
117
- end
118
-
119
- # get the cents value of the object
120
- def cents
121
- @cents
122
- end
123
-
124
- # multiply money by fixnum
125
- def *(fixnum)
126
- Money.new(cents * fixnum, currency)
127
- end
128
-
129
- # divide money by fixnum
130
- def /(fixnum)
131
- Money.new(cents / fixnum, currency)
132
- end
133
-
134
- # Test if the money amount is zero
135
- def zero?
136
- cents == 0
137
- end
138
-
139
-
140
- # Creates a formatted price string according to several rules. The following
141
- # options are supported: :display_free, :with_currency, :no_cents, :symbol
142
- # and :html.
143
- #
144
- # === +:display_free+
145
- #
146
- # Whether a zero amount of money should be formatted of "free" or as the
147
- # supplied string.
148
- #
149
- # Money.us_dollar(0).format(:display_free => true) => "free"
150
- # Money.us_dollar(0).format(:display_free => "gratis") => "gratis"
151
- # Money.us_dollar(0).format => "$0.00"
152
- #
153
- # === +:with_currency+
154
- #
155
- # Whether the currency name should be appended to the result string.
156
- #
157
- # Money.ca_dollar(100).format => "$1.00"
158
- # Money.ca_dollar(100).format(:with_currency => true) => "$1.00 CAD"
159
- # Money.us_dollar(85).format(:with_currency => true) => "$0.85 USD"
160
- #
161
- # === +:no_cents+
162
- #
163
- # Whether cents should be omitted.
164
- #
165
- # Money.ca_dollar(100).format(:no_cents => true) => "$1"
166
- # Money.ca_dollar(599).format(:no_cents => true) => "$5"
167
- #
168
- # Money.ca_dollar(570).format(:no_cents => true, :with_currency => true) => "$5 CAD"
169
- # Money.ca_dollar(39000).format(:no_cents => true) => "$390"
170
- #
171
- # === +:symbol+
172
- #
173
- # Whether a money symbol should be prepended to the result string. The default is true.
174
- # This method attempts to pick a symbol that's suitable for the given currency.
175
- #
176
- # Money.new(100, "USD") => "$1.00"
177
- # Money.new(100, "GBP") => "£1.00"
178
- # Money.new(100, "EUR") => "€1.00"
179
- #
180
- # # Same thing.
181
- # Money.new(100, "USD").format(:symbol => true) => "$1.00"
182
- # Money.new(100, "GBP").format(:symbol => true) => "£1.00"
183
- # Money.new(100, "EUR").format(:symbol => true) => "€1.00"
184
- #
185
- # You can specify a false expression or an empty string to disable prepending
186
- # a money symbol:
187
- #
188
- # Money.new(100, "USD").format(:symbol => false) => "1.00"
189
- # Money.new(100, "GBP").format(:symbol => nil) => "1.00"
190
- # Money.new(100, "EUR").format(:symbol => "") => "1.00"
191
- #
192
- #
193
- # If the symbol for the given currency isn't known, then it will default
194
- # to "$" as symbol:
195
- #
196
- # Money.new(100, "AWG").format(:symbol => true) => "$1.00"
197
- #
198
- # You can specify a string as value to enforce using a particular symbol:
199
- #
200
- # Money.new(100, "AWG").format(:symbol => "ƒ") => "ƒ1.00"
201
- #
202
- # === +:html+
203
- #
204
- # Whether the currency should be HTML-formatted. Only useful in combination with +:with_currency+.
205
- #
206
- # Money.ca_dollar(570).format(:html => true, :with_currency => true)
207
- # => "$5.70 <span class=\"currency\">CAD</span>"
208
- def format(*rules)
209
- # support for old format parameters
210
- rules = normalize_formatting_rules(rules)
211
-
212
- if cents == 0
213
- if rules[:display_free].respond_to?(:to_str)
214
- return rules[:display_free]
215
- elsif rules[:display_free]
216
- return "free"
217
- end
218
- end
219
-
220
- if rules.has_key?(:symbol)
221
- if rules[:symbol] === true
222
- symbol = SYMBOLS[currency] || "$"
223
- elsif rules[:symbol]
224
- symbol = rules[:symbol]
225
- else
226
- symbol = ""
227
- end
228
- else
229
- symbol = SYMBOLS[currency] || "$"
230
- end
231
-
232
- if rules[:no_cents]
233
- formatted = sprintf("#{symbol}%d", cents.to_f / 100)
234
- else
235
- formatted = sprintf("#{symbol}%.2f", cents.to_f / 100)
236
- end
237
-
238
- # Commify ("10000" => "10,000")
239
- formatted.gsub!(/(\d)(?=\d{3}+(?:\.|$))(\d{3}\..*)?/,'\1,\2')
240
-
241
- if rules[:with_currency]
242
- formatted << " "
243
- formatted << '<span class="currency">' if rules[:html]
244
- formatted << currency
245
- formatted << '</span>' if rules[:html]
246
- end
247
- formatted
248
- end
249
-
250
- # Returns the amount of money as a string.
251
- #
252
- # Money.ca_dollar(100).to_s => "1.00"
253
- def to_s
254
- sprintf("%.2f", cents / 100.00)
255
- end
256
-
257
- # Recieve the amount of this money object in another currency.
258
- def exchange_to(other_currency)
259
- Money.new(@bank.exchange(self.cents, currency, other_currency), other_currency)
260
- end
261
-
262
- # Recieve a money object with the same amount as the current Money object
263
- # in american dollar
264
- def as_us_dollar
265
- exchange_to("USD")
266
- end
267
-
268
- # Recieve a money object with the same amount as the current Money object
269
- # in canadian dollar
270
- def as_ca_dollar
271
- exchange_to("CAD")
272
- end
273
-
274
- # Recieve a money object with the same amount as the current Money object
275
- # in euro
276
- def as_euro
277
- exchange_to("EUR")
278
- end
279
-
280
- # Conversation to self
281
- def to_money
282
- self
283
- end
284
-
285
- private
286
-
287
- def normalize_formatting_rules(rules)
288
- if rules.size == 1
289
- rules = rules.pop
290
- rules = { rules => true } if rules.is_a?(Symbol)
291
- else
292
- rules = rules.inject({}) do |h,s|
293
- h[s] = true
294
- h
295
- end
296
- end
297
- rules
298
- end
299
- end
1
+ require 'money/variable_exchange_bank'
2
+
3
+ # Represents an amount of money in a certain currency.
4
+ class Money
5
+ include Comparable
6
+
7
+ attr_reader :cents, :currency, :bank
8
+
9
+ class << self
10
+ # Each Money object is associated to a bank object, which is responsible
11
+ # for currency exchange. This property allows one to specify the default
12
+ # bank object.
13
+ #
14
+ # bank1 = MyBank.new
15
+ # bank2 = MyOtherBank.new
16
+ #
17
+ # Money.default_bank = bank1
18
+ # money1 = Money.new(10)
19
+ # money1.bank # => bank1
20
+ #
21
+ # Money.default_bank = bank2
22
+ # money2 = Money.new(10)
23
+ # money2.bank # => bank2
24
+ # money1.bank # => bank1
25
+ #
26
+ # The default value for this property is an instance if VariableExchangeBank.
27
+ # It allows one to specify custom exchange rates:
28
+ #
29
+ # Money.default_bank.add_rate("USD", "CAD", 1.24515)
30
+ # Money.default_bank.add_rate("CAD", "USD", 0.803115)
31
+ # Money.us_dollar(100).exchange_to("CAD") # => Money.ca_dollar(124)
32
+ # Money.ca_dollar(100).exchange_to("USD") # => Money.us_dollar(80)
33
+ attr_accessor :default_bank
34
+
35
+ # The default currency, which is used when <tt>Money.new</tt> is called
36
+ # without an explicit currency argument. The default value is "USD".
37
+ attr_accessor :default_currency
38
+ end
39
+
40
+ self.default_bank = VariableExchangeBank.instance
41
+ self.default_currency = "USD"
42
+
43
+
44
+ # Create a new money object with value 0.
45
+ def self.empty(currency = default_currency)
46
+ Money.new(0, currency)
47
+ end
48
+
49
+ # Creates a new Money object of the given value, using the Canadian dollar currency.
50
+ def self.ca_dollar(cents)
51
+ Money.new(cents, "CAD")
52
+ end
53
+
54
+ # Creates a new Money object of the given value, using the American dollar currency.
55
+ def self.us_dollar(cents)
56
+ Money.new(cents, "USD")
57
+ end
58
+
59
+ # Creates a new Money object of the given value, using the Euro currency.
60
+ def self.euro(cents)
61
+ Money.new(cents, "EUR")
62
+ end
63
+
64
+ def self.add_rate(from_currency, to_currency, rate)
65
+ Money.default_bank.add_rate(from_currency, to_currency, rate)
66
+ end
67
+
68
+
69
+ # Creates a new money object.
70
+ # Money.new(100)
71
+ #
72
+ # Alternativly you can use the convinience methods like
73
+ # Money.ca_dollar and Money.us_dollar
74
+ def initialize(cents, currency = Money.default_currency, bank = Money.default_bank)
75
+ @cents = cents.round
76
+ if currency.is_a?(Hash)
77
+ # Earlier versions of Money wrongly documented the constructor as being able
78
+ # to accept something like this:
79
+ #
80
+ # Money.new(50, :currency => "USD")
81
+ #
82
+ # We retain compatibility here.
83
+ @currency = currency[:currency] || Money.default_currency
84
+ else
85
+ @currency = currency
86
+ end
87
+ @bank = bank
88
+ end
89
+
90
+ # Checks whether two money objects have the same currency and the same amount.
91
+ # Checks against money objects with a different currency and checks against
92
+ # objects that do not respond to #to_money will always return false.
93
+ def ==(other_money)
94
+ if other_money.respond_to?(:to_money)
95
+ other_money = other_money.to_money
96
+ cents == other_money.cents && bank.same_currency?(currency, other_money.currency)
97
+ else
98
+ false
99
+ end
100
+ end
101
+
102
+ # Compares this money object against another object. +other_money+ must respond
103
+ # to #to_money.
104
+ #
105
+ # If +other_money+ is of a different currency, then +other_money+ will first be
106
+ # converted into this money object's currency by calling +other_money.exchange+.
107
+ #
108
+ # Comparisons against objects that do not respond to #to_money will cause an
109
+ # ArgumentError to be raised.
110
+ def <=>(other_money)
111
+ if other_money.respond_to?(:to_money)
112
+ other_money = other_money.to_money
113
+ if bank.same_currency?(currency, other_money.currency)
114
+ cents <=> other_money.cents
115
+ else
116
+ cents <=> other_money.exchange_to(currency).cents
117
+ end
118
+ else
119
+ raise ArgumentError, "comparison of #{self.class} with #{other_money.inspect} failed"
120
+ end
121
+ end
122
+
123
+ def +(other_money)
124
+ if currency == other_money.currency
125
+ Money.new(cents + other_money.cents, other_money.currency)
126
+ else
127
+ Money.new(cents + other_money.exchange_to(currency).cents, currency)
128
+ end
129
+ end
130
+
131
+ def -(other_money)
132
+ if currency == other_money.currency
133
+ Money.new(cents - other_money.cents, other_money.currency)
134
+ else
135
+ Money.new(cents - other_money.exchange_to(currency).cents, currency)
136
+ end
137
+ end
138
+
139
+ # get the cents value of the object
140
+ def cents
141
+ @cents
142
+ end
143
+
144
+ # multiply money by fixnum
145
+ def *(fixnum)
146
+ Money.new(cents * fixnum, currency)
147
+ end
148
+
149
+ # divide money by money or fixnum
150
+ def /(val)
151
+ if val.is_a?(Money)
152
+ if currency == val.currency
153
+ cents / val.cents.to_f
154
+ else
155
+ cents / val.exchange_to(currency).cents.to_f
156
+ end
157
+ else
158
+ Money.new(cents / val, currency)
159
+ end
160
+ end
161
+
162
+ # Test if the money amount is zero
163
+ def zero?
164
+ cents == 0
165
+ end
166
+
167
+
168
+ # Creates a formatted price string according to several rules. The following
169
+ # options are supported: :display_free, :with_currency, :no_cents, :symbol,
170
+ # :separator, :delimiter and :html.
171
+ #
172
+ # === +:display_free+
173
+ #
174
+ # Whether a zero amount of money should be formatted of "free" or as the
175
+ # supplied string.
176
+ #
177
+ # Money.us_dollar(0).format(:display_free => true) => "free"
178
+ # Money.us_dollar(0).format(:display_free => "gratis") => "gratis"
179
+ # Money.us_dollar(0).format => "$0.00"
180
+ #
181
+ # === +:with_currency+
182
+ #
183
+ # Whether the currency name should be appended to the result string.
184
+ #
185
+ # Money.ca_dollar(100).format => "$1.00"
186
+ # Money.ca_dollar(100).format(:with_currency => true) => "$1.00 CAD"
187
+ # Money.us_dollar(85).format(:with_currency => true) => "$0.85 USD"
188
+ #
189
+ # === +:no_cents+
190
+ #
191
+ # Whether cents should be omitted.
192
+ #
193
+ # Money.ca_dollar(100).format(:no_cents => true) => "$1"
194
+ # Money.ca_dollar(599).format(:no_cents => true) => "$5"
195
+ #
196
+ # Money.ca_dollar(570).format(:no_cents => true, :with_currency => true) => "$5 CAD"
197
+ # Money.ca_dollar(39000).format(:no_cents => true) => "$390"
198
+ #
199
+ # === +:symbol+
200
+ #
201
+ # Whether a money symbol should be prepended to the result string. The default is true.
202
+ # This method attempts to pick a symbol that's suitable for the given currency.
203
+ #
204
+ # Money.new(100, "USD") => "$1.00"
205
+ # Money.new(100, "GBP") => "£1.00"
206
+ # Money.new(100, "EUR") => "€1.00"
207
+ #
208
+ # # Same thing.
209
+ # Money.new(100, "USD").format(:symbol => true) => "$1.00"
210
+ # Money.new(100, "GBP").format(:symbol => true) => "£1.00"
211
+ # Money.new(100, "EUR").format(:symbol => true) => "€1.00"
212
+ #
213
+ # You can specify a false expression or an empty string to disable prepending
214
+ # a money symbol:
215
+ #
216
+ # Money.new(100, "USD").format(:symbol => false) => "1.00"
217
+ # Money.new(100, "GBP").format(:symbol => nil) => "1.00"
218
+ # Money.new(100, "EUR").format(:symbol => "") => "1.00"
219
+ #
220
+ #
221
+ # If the symbol for the given currency isn't known, then it will default
222
+ # to "$" as symbol:
223
+ #
224
+ # Money.new(100, "AWG").format(:symbol => true) => "$1.00"
225
+ #
226
+ # You can specify a string as value to enforce using a particular symbol:
227
+ #
228
+ # Money.new(100, "AWG").format(:symbol => "ƒ") => "ƒ1.00"
229
+ #
230
+ # === +:separator+
231
+ #
232
+ # Whether the currency should be separated by the specified character or '.'
233
+ #
234
+ # If a string is specified, it's value is used:
235
+ #
236
+ # Money.new(100, "USD").format(:separator => ",") => "$1,00"
237
+ #
238
+ # If the separator for a given currency isn't known, then it will default to
239
+ # "." as separator:
240
+ #
241
+ # Money.new(100, "FOO").format => "$1.00"
242
+ #
243
+ # === +:delimiter+
244
+ #
245
+ # Whether the currency should be delimited by the specified character or ','
246
+ #
247
+ # If false is specified, no delimiter is used:
248
+ #
249
+ # Money.new(100000, "USD").format(:delimiter => false) => "1000.00"
250
+ # Money.new(100000, "USD").format(:delimiter => nil) => "1000.00"
251
+ # Money.new(100000, "USD").format(:delimiter => "") => "1000.00"
252
+ #
253
+ # If a string is specified, it's value is used:
254
+ #
255
+ # Money.new(100000, "USD").format(:delimiter => ".") => "$1.000.00"
256
+ #
257
+ # If the delimiter for a given currency isn't known, then it will default to
258
+ # "," as delimiter:
259
+ #
260
+ # Money.new(100000, "FOO").format => "$1,000.00"
261
+ #
262
+ # === +:html+
263
+ #
264
+ # Whether the currency should be HTML-formatted. Only useful in combination with +:with_currency+.
265
+ #
266
+ # Money.ca_dollar(570).format(:html => true, :with_currency => true)
267
+ # => "$5.70 <span class=\"currency\">CAD</span>"
268
+ def format(*rules)
269
+ # support for old format parameters
270
+ rules = normalize_formatting_rules(rules)
271
+
272
+ if cents == 0
273
+ if rules[:display_free].respond_to?(:to_str)
274
+ return rules[:display_free]
275
+ elsif rules[:display_free]
276
+ return "free"
277
+ end
278
+ end
279
+
280
+ if rules.has_key?(:symbol)
281
+ if rules[:symbol] === true
282
+ symbol = SYMBOLS[currency] || "$"
283
+ elsif rules[:symbol]
284
+ symbol = rules[:symbol]
285
+ else
286
+ symbol = ""
287
+ end
288
+ else
289
+ symbol = SYMBOLS[currency] || "$"
290
+ end
291
+
292
+ if rules[:no_cents]
293
+ formatted = sprintf("#{symbol}%d", cents.to_f / 100)
294
+ else
295
+ formatted = sprintf("#{symbol}%.2f", cents.to_f / 100)
296
+ end
297
+
298
+ delimiter = DELIMITERS[currency] || ","
299
+ # Determine delimiter
300
+ if rules.has_key?(:delimiter)
301
+ if rules[:delimiter] === false or rules[:delimiter].nil?
302
+ delimiter = ""
303
+ elsif rules[:delimiter]
304
+ delimiter = rules[:delimiter]
305
+ end
306
+ end
307
+
308
+ # Apply delimiter
309
+ formatted.gsub!(/(\d)(?=\d{3}+(?:\.|$))(\d{3}\..*)?/, "\\1#{delimiter}\\2")
310
+
311
+ separator = SEPARATORS[currency] || "."
312
+ # Determine separator
313
+ if rules.has_key?(:separator) and rules[:separator]
314
+ separator = rules[:separator]
315
+ end
316
+
317
+ # Apply separator
318
+ formatted.sub!(/\.(\d{2})$/, "#{separator}\\1")
319
+
320
+ if rules[:with_currency]
321
+ formatted << " "
322
+ formatted << '<span class="currency">' if rules[:html]
323
+ formatted << currency
324
+ formatted << '</span>' if rules[:html]
325
+ end
326
+ formatted
327
+ end
328
+
329
+ # Returns the amount of money as a string.
330
+ #
331
+ # Money.ca_dollar(100).to_s => "1.00"
332
+ def to_s
333
+ sprintf("%.2f", cents / 100.00)
334
+ end
335
+
336
+ # Return the amount of money as a float. Floating points cannot guarantee
337
+ # precision. Therefore, this function should only be used when you no longer
338
+ # need to represent currency or working with another system that requires
339
+ # decimals.
340
+ #
341
+ # Money.us_dollar(100).to_f => 1.0
342
+ def to_f
343
+ cents / 100.0
344
+ end
345
+
346
+ # Recieve the amount of this money object in another currency.
347
+ def exchange_to(other_currency)
348
+ Money.new(@bank.exchange(self.cents, currency, other_currency), other_currency)
349
+ end
350
+
351
+ # Recieve a money object with the same amount as the current Money object
352
+ # in american dollar
353
+ def as_us_dollar
354
+ exchange_to("USD")
355
+ end
356
+
357
+ # Recieve a money object with the same amount as the current Money object
358
+ # in canadian dollar
359
+ def as_ca_dollar
360
+ exchange_to("CAD")
361
+ end
362
+
363
+ # Recieve a money object with the same amount as the current Money object
364
+ # in euro
365
+ def as_euro
366
+ exchange_to("EUR")
367
+ end
368
+
369
+ # Conversation to self
370
+ def to_money
371
+ self
372
+ end
373
+
374
+ private
375
+
376
+ def normalize_formatting_rules(rules)
377
+ if rules.size == 1
378
+ rules = rules.pop
379
+ rules = { rules => true } if rules.is_a?(Symbol)
380
+ else
381
+ rules = rules.inject({}) do |h,s|
382
+ h[s] = true
383
+ h
384
+ end
385
+ end
386
+ rules
387
+ end
388
+ end