money 2.1.5 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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