money 6.5.1 → 6.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/AUTHORS +7 -0
- data/CHANGELOG.md +15 -0
- data/README.md +121 -3
- data/Rakefile +0 -1
- data/config/currency_iso.json +8 -8
- data/lib/money/bank/base.rb +0 -2
- data/lib/money/bank/variable_exchange.rb +80 -85
- data/lib/money/currency.rb +50 -35
- data/lib/money/money/arithmetic.rb +9 -9
- data/lib/money/money/formatting.rb +30 -8
- data/lib/money/money.rb +32 -10
- data/lib/money/rates_store/memory.rb +120 -0
- data/lib/money/version.rb +1 -1
- data/money.gemspec +1 -1
- data/spec/bank/base_spec.rb +62 -58
- data/spec/bank/single_currency_spec.rb +10 -6
- data/spec/bank/variable_exchange_spec.rb +205 -223
- data/spec/currency/loader_spec.rb +20 -0
- data/spec/currency_spec.rb +275 -243
- data/spec/money/arithmetic_spec.rb +16 -34
- data/spec/money/formatting_spec.rb +19 -12
- data/spec/money_spec.rb +86 -97
- data/spec/rates_store/memory_spec.rb +71 -0
- data/spec/spec_helper.rb +10 -0
- metadata +10 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c65fe09cbae38c4022a53cdc0c6b5cba47e72930
|
4
|
+
data.tar.gz: 5de5a0732f90ab4af46ef801378a7a6161b5324d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bba3d4bc1dfc26c28ed9e4720a815c0bf36c6dd0376c17a664cb70d066d5c436c29da795abade5bd61c0797808f5969f52fa696d7bfeb874333ad11411745583
|
7
|
+
data.tar.gz: 1a38008c4890e953e1002485fd1098c935ed370cf4e05648846327302d2202fed8adf96df22b37cb98abf7de5b36a8cc87bc7d168d7ab606f2d87a28d87e4f32
|
data/.travis.yml
CHANGED
data/AUTHORS
CHANGED
@@ -16,6 +16,7 @@ Bill DeRusha
|
|
16
16
|
Bodaniel Jeanes
|
17
17
|
Brian Jones
|
18
18
|
bUg.
|
19
|
+
Cade Truitt
|
19
20
|
Casper Thomsen
|
20
21
|
Chad Boyd
|
21
22
|
Choongmin Lee
|
@@ -30,6 +31,7 @@ Edwin Vlieg
|
|
30
31
|
Eloy
|
31
32
|
Evan Alter
|
32
33
|
Exoth
|
34
|
+
Filipe Goncalves
|
33
35
|
François Beausoleil
|
34
36
|
François Klingler
|
35
37
|
Francisco Trindade
|
@@ -68,10 +70,13 @@ Mateusz Wolsza
|
|
68
70
|
Matias Korhonen
|
69
71
|
Matt Jankowski
|
70
72
|
Matthew McEachen
|
73
|
+
Max Melentiev
|
71
74
|
Michael J. Cohen
|
72
75
|
Michael Irwin
|
73
76
|
Michael Reinsch
|
77
|
+
Michael Rodrigues
|
74
78
|
Mikael Wikman
|
79
|
+
Mike Herrera
|
75
80
|
Mike Połétyn
|
76
81
|
Musannif Zahir
|
77
82
|
Neil Middleton
|
@@ -111,6 +116,8 @@ Tobias Schmidt
|
|
111
116
|
Tom Lianza
|
112
117
|
tommeier
|
113
118
|
Troels Knak-Nielsen
|
119
|
+
Tsyren Ochirov
|
114
120
|
Wei Zhu
|
115
121
|
Zubin Henner
|
116
122
|
Бродяной Александр
|
123
|
+
Douglas Miller
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
## Next release
|
4
4
|
|
5
|
+
- Fixed VariableExchange#exchange_with for big numbers.
|
6
|
+
- Add Currency symbol translation support
|
7
|
+
- `Currency.all` raises a more helpful error message
|
8
|
+
(`Currency::MissingAttributeError`)if a currency has no priority
|
5
9
|
- `Currency` implements `Enumerable`.
|
6
10
|
- `Currency#<=>` sorts alphabetically by `id` if the `priority`s are the same,
|
7
11
|
and no longer raises an error if one of the priorities is missing.
|
@@ -16,6 +20,17 @@
|
|
16
20
|
`.ca_dollar`, and `.euro`.
|
17
21
|
- Add helper methods for British pounds: `Money.pound_sterling` and
|
18
22
|
`Money.gbp`.
|
23
|
+
- Add `Money.from_amount` to create money from a value in units instead of
|
24
|
+
fractional units.
|
25
|
+
- Changed CHF symbol from 'Fr' to 'CHF'
|
26
|
+
- Changed CLF exponent from 0 to 4
|
27
|
+
- Changed CLP subunit_to_unit from 1 to 100
|
28
|
+
- Minor fixes to prevent warnings on unused variables and the redefinition of
|
29
|
+
`Money.default_currency`
|
30
|
+
- `Money#==` changed to acknowledge that 0 in one currency is equal to 0 in any currency.
|
31
|
+
- Changed KRW subunit_to_unit from 100 to 1
|
32
|
+
- Decouple exchange rates storage from bank objects and formalize storage public API. Default is `Money::RatesStore::Memory`.
|
33
|
+
- `Currency.new` now a singleton by its id
|
19
34
|
|
20
35
|
## 6.5.1
|
21
36
|
- Fix format for BYR currency
|
data/README.md
CHANGED
@@ -79,9 +79,19 @@ Money.new(1000, "USD") - Money.new(200, "USD") == Money.new(800, "USD")
|
|
79
79
|
Money.new(1000, "USD") / 5 == Money.new(200, "USD")
|
80
80
|
Money.new(1000, "USD") * 5 == Money.new(5000, "USD")
|
81
81
|
|
82
|
+
# Unit to subunit conversions
|
83
|
+
Money.from_amount(5, "USD") == Money.new(500, "USD") # 5 USD
|
84
|
+
Money.from_amount(5, "JPY") == Money.new(5, "JPY") # 5 JPY
|
85
|
+
Money.from_amount(5, "TND") == Money.new(5000, "TND") # 5 TND
|
86
|
+
|
82
87
|
# Currency conversions
|
83
88
|
some_code_to_setup_exchange_rates
|
84
89
|
Money.new(1000, "USD").exchange_to("EUR") == Money.new(some_value, "EUR")
|
90
|
+
|
91
|
+
# Formatting (see Formatting section for more options)
|
92
|
+
Money.new(100, "USD").format #=> "$1.00"
|
93
|
+
Money.new(100, "GBP").format #=> "£1.00"
|
94
|
+
Money.new(100, "EUR").format #=> "€1.00"
|
85
95
|
```
|
86
96
|
|
87
97
|
## Currency
|
@@ -233,11 +243,116 @@ Money.add_rate("USD", "EUR", 0.5)
|
|
233
243
|
Money.new(1000, "EUR") + Money.new(1000, "USD") == Money.new(1500, "EUR")
|
234
244
|
```
|
235
245
|
|
236
|
-
|
246
|
+
### Exchange rate stores
|
247
|
+
|
248
|
+
The default bank is initialized with an in-memory store for exchange rates.
|
249
|
+
|
250
|
+
```ruby
|
251
|
+
Money.default_bank = Money::Bank::VariableExchange.new(Money::RatesStore::Memory.new)
|
252
|
+
```
|
253
|
+
|
254
|
+
You can pass you own store implementation, ie. for storing and retrieving rates off a database, file, cache, etc.
|
255
|
+
|
256
|
+
```ruby
|
257
|
+
Money.default_bank = Money::Bank::VariableExchange.new(MyCustomStore.new)
|
258
|
+
```
|
259
|
+
|
260
|
+
Stores must implement the following interface:
|
261
|
+
|
262
|
+
```ruby
|
263
|
+
# Add new exchange rate.
|
264
|
+
# @param [String] iso_from Currency ISO code. ex. 'USD'
|
265
|
+
# @param [String] iso_to Currency ISO code. ex. 'CAD'
|
266
|
+
# @param [Numeric] rate Exchange rate. ex. 0.0016
|
267
|
+
#
|
268
|
+
# @return [Numeric] rate.
|
269
|
+
def add_rate(iso_from, iso_to, rate); end
|
270
|
+
|
271
|
+
# Get rate. Must be idempotent. ie. adding the same rate must not produce duplicates.
|
272
|
+
# @param [String] iso_from Currency ISO code. ex. 'USD'
|
273
|
+
# @param [String] iso_to Currency ISO code. ex. 'CAD'
|
274
|
+
#
|
275
|
+
# @return [Numeric] rate.
|
276
|
+
def get_rate(iso_from, iso_to); end
|
277
|
+
|
278
|
+
# Iterate over rate tuples (iso_from, iso_to, rate)
|
279
|
+
#
|
280
|
+
# @yieldparam iso_from [String] Currency ISO string.
|
281
|
+
# @yieldparam iso_to [String] Currency ISO string.
|
282
|
+
# @yieldparam rate [Numeric] Exchange rate.
|
283
|
+
#
|
284
|
+
# @return [Enumerator]
|
285
|
+
#
|
286
|
+
# @example
|
287
|
+
# store.each_rate do |iso_from, iso_to, rate|
|
288
|
+
# puts [iso_from, iso_to, rate].join
|
289
|
+
# end
|
290
|
+
def each_rate(&block); end
|
291
|
+
|
292
|
+
# Wrap store operations in a thread-safe transaction
|
293
|
+
# (or IO or Database transaction, depending on your implementation)
|
294
|
+
#
|
295
|
+
# @yield [n] Block that will be wrapped in transaction.
|
296
|
+
#
|
297
|
+
# @example
|
298
|
+
# store.transaction do
|
299
|
+
# store.add_rate('USD', 'CAD', 0.9)
|
300
|
+
# store.add_rate('USD', 'CLP', 0.0016)
|
301
|
+
# end
|
302
|
+
def transaction(&block); end
|
303
|
+
|
304
|
+
# Serialize store and its content to make Marshal.dump work.
|
305
|
+
#
|
306
|
+
# Returns an array with store class and any arguments needed to initialize the store in the current state.
|
307
|
+
|
308
|
+
# @return [Array] [class, arg1, arg2]
|
309
|
+
def marshal_dump; end
|
310
|
+
```
|
311
|
+
|
312
|
+
The following example implements an `ActiveRecord` store to save exchange rates to a database.
|
313
|
+
|
314
|
+
```ruby
|
315
|
+
# DB columns :from[String], :to[String], :rate[Float]
|
316
|
+
|
317
|
+
class ExchangeRate < ActiveRecord::Base
|
318
|
+
def self.get_rate(from_iso_code, to_iso_code)
|
319
|
+
rate = find_by_from_and_to(from_iso_code, to_iso_code)
|
320
|
+
rate.present? ? rate.rate : nil
|
321
|
+
end
|
322
|
+
|
323
|
+
def self.add_rate(from_iso_code, to_iso_code, rate)
|
324
|
+
exrate = find_or_initialize_by_from_and_to(from_iso_code, to_iso_code)
|
325
|
+
exrate.rate = rate
|
326
|
+
exrate.save!
|
327
|
+
end
|
328
|
+
end
|
329
|
+
```
|
330
|
+
|
331
|
+
Now you can use it with the default bank.
|
332
|
+
|
333
|
+
```ruby
|
334
|
+
Money.default_bank = Money::Bank::VariableExchange.new(ExchangeRate)
|
335
|
+
|
336
|
+
# Add to the underlying store
|
337
|
+
Money.default_bank.add_rate('USD', 'CAD', 0.9)
|
338
|
+
# Retrieve from the underlying store
|
339
|
+
Money.default_bank.get_rate('USD', 'CAD') # => 0.9
|
340
|
+
# Exchanging amounts just works.
|
341
|
+
Money.new(1000, 'USD').exchange_to('CAD') #=> #<Money fractional:900 currency:CAD>
|
342
|
+
```
|
343
|
+
|
344
|
+
There is nothing stopping you from creating store objects which scrapes
|
237
345
|
[XE](http://www.xe.com) for the current rates or just returns `rand(2)`:
|
238
346
|
|
239
347
|
``` ruby
|
240
|
-
Money.default_bank =
|
348
|
+
Money.default_bank = Money::Bank::VariableExchange.new(StoreWhichScrapesXeDotCom.new)
|
349
|
+
```
|
350
|
+
|
351
|
+
You can also implement your own Bank to calculate exchanges differently.
|
352
|
+
Different banks can share Stores.
|
353
|
+
|
354
|
+
```ruby
|
355
|
+
Money.default_bank = MyCustomBank.new(Money::RatesStore::Memory.new)
|
241
356
|
```
|
242
357
|
|
243
358
|
If you wish to disable automatic currency conversion to prevent arithmetic when
|
@@ -254,6 +369,7 @@ implementations.
|
|
254
369
|
|
255
370
|
- [eu_central_bank](http://github.com/RubyMoney/eu_central_bank)
|
256
371
|
- [google_currency](http://github.com/RubyMoney/google_currency)
|
372
|
+
- [money-json-rates](https://github.com/askuratovsky/money-json-rates)
|
257
373
|
- [nordea](https://github.com/k33l0r/nordea)
|
258
374
|
- [nbrb_currency](https://github.com/slbug/nbrb_currency)
|
259
375
|
- [money-open-exchange-rates](https://github.com/spk/money-open-exchange-rates)
|
@@ -296,7 +412,9 @@ If you wish to disable this feature:
|
|
296
412
|
Money.use_i18n = false
|
297
413
|
```
|
298
414
|
|
299
|
-
|
415
|
+
## Formatting
|
416
|
+
|
417
|
+
There are several formatting rules for when `Money#format` is called. For more information, check out the [formatting module](https://github.com/RubyMoney/money/blob/master/lib/money/money/formatting.rb).*
|
300
418
|
|
301
419
|
## Migration Notes
|
302
420
|
|
data/Rakefile
CHANGED
data/config/currency_iso.json
CHANGED
@@ -419,8 +419,8 @@
|
|
419
419
|
"priority": 100,
|
420
420
|
"iso_code": "CHF",
|
421
421
|
"name": "Swiss Franc",
|
422
|
-
"symbol": "
|
423
|
-
"alternate_symbols": ["SFr", "
|
422
|
+
"symbol": "CHF",
|
423
|
+
"alternate_symbols": ["SFr", "Fr"],
|
424
424
|
"subunit": "Rappen",
|
425
425
|
"subunit_to_unit": 100,
|
426
426
|
"symbol_first": true,
|
@@ -437,7 +437,7 @@
|
|
437
437
|
"symbol": "UF",
|
438
438
|
"alternate_symbols": [],
|
439
439
|
"subunit": "Peso",
|
440
|
-
"subunit_to_unit":
|
440
|
+
"subunit_to_unit": 10000,
|
441
441
|
"symbol_first": true,
|
442
442
|
"html_entity": "₱",
|
443
443
|
"decimal_mark": ",",
|
@@ -452,7 +452,7 @@
|
|
452
452
|
"disambiguate_symbol": "CLP",
|
453
453
|
"alternate_symbols": [],
|
454
454
|
"subunit": "Peso",
|
455
|
-
"subunit_to_unit":
|
455
|
+
"subunit_to_unit": 1,
|
456
456
|
"symbol_first": true,
|
457
457
|
"html_entity": "$",
|
458
458
|
"decimal_mark": ",",
|
@@ -1036,14 +1036,14 @@
|
|
1036
1036
|
"name": "Jordanian Dinar",
|
1037
1037
|
"symbol": "د.ا",
|
1038
1038
|
"alternate_symbols": ["JD"],
|
1039
|
-
"subunit": "
|
1040
|
-
"subunit_to_unit":
|
1039
|
+
"subunit": "Fils",
|
1040
|
+
"subunit_to_unit": 1000,
|
1041
1041
|
"symbol_first": true,
|
1042
1042
|
"html_entity": "",
|
1043
1043
|
"decimal_mark": ".",
|
1044
1044
|
"thousands_separator": ",",
|
1045
1045
|
"iso_numeric": "400",
|
1046
|
-
"smallest_denomination":
|
1046
|
+
"smallest_denomination": 5
|
1047
1047
|
},
|
1048
1048
|
"jpy": {
|
1049
1049
|
"priority": 6,
|
@@ -1142,7 +1142,7 @@
|
|
1142
1142
|
"name": "South Korean Won",
|
1143
1143
|
"symbol": "₩",
|
1144
1144
|
"subunit": null,
|
1145
|
-
"subunit_to_unit":
|
1145
|
+
"subunit_to_unit": 1,
|
1146
1146
|
"alternate_symbols": [],
|
1147
1147
|
"symbol_first": true,
|
1148
1148
|
"html_entity": "₩",
|
data/lib/money/bank/base.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'money/bank/base'
|
2
|
+
require 'money/rates_store/memory'
|
2
3
|
require 'json'
|
3
4
|
require 'yaml'
|
4
5
|
|
@@ -15,42 +16,58 @@ class Money
|
|
15
16
|
# conversion rates. One must manually specify them with +add_rate+, after
|
16
17
|
# which one can perform exchanges with +#exchange_with+.
|
17
18
|
#
|
19
|
+
# Exchange rates are stored in memory using +Money::RatesStore::Memory+ by default.
|
20
|
+
# Pass custom rates stores for other types of storage (file, database, etc)
|
21
|
+
#
|
18
22
|
# @example
|
19
23
|
# bank = Money::Bank::VariableExchange.new
|
20
24
|
# bank.add_rate("USD", "CAD", 1.24515)
|
21
25
|
# bank.add_rate("CAD", "USD", 0.803115)
|
22
26
|
#
|
23
|
-
# c1 =
|
24
|
-
# c2 =
|
27
|
+
# c1 = Money.new(100_00, "USD")
|
28
|
+
# c2 = Money.new(100_00, "CAD")
|
25
29
|
#
|
26
30
|
# # Exchange 100 USD to CAD:
|
27
|
-
# bank.exchange_with(c1, "CAD") #=> #<Money
|
31
|
+
# bank.exchange_with(c1, "CAD") #=> #<Money fractional:12451 currency:CAD>
|
28
32
|
#
|
29
33
|
# # Exchange 100 CAD to USD:
|
30
|
-
# bank.exchange_with(c2, "USD") #=> #<Money
|
34
|
+
# bank.exchange_with(c2, "USD") #=> #<Money fractional:8031 currency:USD>
|
35
|
+
#
|
36
|
+
# # With custom exchange rates storage
|
37
|
+
# redis_store = MyCustomRedisStore.new(host: 'localhost:6379')
|
38
|
+
# bank = Money::Bank::VariableExchange.new(redis_store)
|
39
|
+
# # Store rates in redis
|
40
|
+
# bank.add_rate 'USD', 'CAD', 0.98
|
41
|
+
# # Get rate from redis
|
42
|
+
# bank.get_rate 'USD', 'CAD'
|
31
43
|
class VariableExchange < Base
|
32
44
|
|
33
|
-
attr_reader :
|
45
|
+
attr_reader :mutex, :store
|
34
46
|
|
35
47
|
# Available formats for importing/exporting rates.
|
36
48
|
RATE_FORMATS = [:json, :ruby, :yaml]
|
49
|
+
SERIALIZER_SEPARATOR = '_TO_'.freeze
|
37
50
|
|
38
|
-
#
|
51
|
+
# Initializes a new +Money::Bank::VariableExchange+ object.
|
52
|
+
# It defaults to using an in-memory, thread safe store instance for
|
53
|
+
# storing exchange rates.
|
39
54
|
#
|
40
|
-
# @
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
55
|
+
# @param [RateStore] st An exchange rate store, used to persist exchange rate pairs.
|
56
|
+
# @yield [n] Optional block to use when rounding after exchanging one
|
57
|
+
# currency for another. See +Money::bank::base+
|
58
|
+
def initialize(st = Money::RatesStore::Memory.new, &block)
|
59
|
+
@store = st
|
60
|
+
super(&block)
|
45
61
|
end
|
46
62
|
|
47
63
|
def marshal_dump
|
48
|
-
[
|
64
|
+
[store.marshal_dump, @rounding_method]
|
49
65
|
end
|
50
66
|
|
51
67
|
def marshal_load(arr)
|
52
|
-
|
53
|
-
@
|
68
|
+
store_info = arr[0]
|
69
|
+
@store = store_info.shift.new(*store_info)
|
70
|
+
@rounding_method = arr[1]
|
54
71
|
end
|
55
72
|
|
56
73
|
# Exchanges the given +Money+ object to a new +Money+ object in
|
@@ -76,14 +93,14 @@ class Money
|
|
76
93
|
# bank.add_rate("USD", "CAD", 1.24515)
|
77
94
|
# bank.add_rate("CAD", "USD", 0.803115)
|
78
95
|
#
|
79
|
-
# c1 =
|
80
|
-
# c2 =
|
96
|
+
# c1 = Money.new(100_00, "USD")
|
97
|
+
# c2 = Money.new(100_00, "CAD")
|
81
98
|
#
|
82
99
|
# # Exchange 100 USD to CAD:
|
83
|
-
# bank.exchange_with(c1, "CAD") #=> #<Money
|
100
|
+
# bank.exchange_with(c1, "CAD") #=> #<Money fractional:12451 currency:CAD>
|
84
101
|
#
|
85
102
|
# # Exchange 100 CAD to USD:
|
86
|
-
# bank.exchange_with(c2, "USD") #=> #<Money
|
103
|
+
# bank.exchange_with(c2, "USD") #=> #<Money fractional:8031 currency:USD>
|
87
104
|
def exchange_with(from, to_currency, &block)
|
88
105
|
to_currency = Currency.wrap(to_currency)
|
89
106
|
if from.currency == to_currency
|
@@ -114,11 +131,12 @@ class Money
|
|
114
131
|
elsif @rounding_method
|
115
132
|
@rounding_method.call(ex)
|
116
133
|
else
|
117
|
-
ex.to_s.
|
134
|
+
ex.to_s.to_d
|
118
135
|
end
|
119
136
|
end
|
120
137
|
|
121
138
|
# Registers a conversion rate and returns it (uses +#set_rate+).
|
139
|
+
# Delegates to +Money::RatesStore::Memory+
|
122
140
|
#
|
123
141
|
# @param [Currency, String, Symbol] from Currency to exchange from.
|
124
142
|
# @param [Currency, String, Symbol] to Currency to exchange to.
|
@@ -134,14 +152,14 @@ class Money
|
|
134
152
|
set_rate(from, to, rate)
|
135
153
|
end
|
136
154
|
|
137
|
-
# Set the rate for the given currencies.
|
155
|
+
# Set the rate for the given currencies.
|
138
156
|
# access.
|
157
|
+
# Delegates to +Money::RatesStore::Memory+
|
139
158
|
#
|
140
159
|
# @param [Currency, String, Symbol] from Currency to exchange from.
|
141
160
|
# @param [Currency, String, Symbol] to Currency to exchange to.
|
142
161
|
# @param [Numeric] rate Rate to use when exchanging currencies.
|
143
|
-
# @param [Hash] opts Options hash to set special parameters
|
144
|
-
# @option opts [Boolean] :without_mutex disables the usage of a mutex
|
162
|
+
# @param [Hash] opts Options hash to set special parameters. Backwards compatibility only.
|
145
163
|
#
|
146
164
|
# @return [Numeric]
|
147
165
|
#
|
@@ -150,21 +168,16 @@ class Money
|
|
150
168
|
# bank.set_rate("USD", "CAD", 1.24515)
|
151
169
|
# bank.set_rate("CAD", "USD", 0.803115)
|
152
170
|
def set_rate(from, to, rate, opts = {})
|
153
|
-
|
154
|
-
if opts[:without_mutex]
|
155
|
-
fn.call
|
156
|
-
else
|
157
|
-
@mutex.synchronize { fn.call }
|
158
|
-
end
|
171
|
+
store.add_rate(Currency.wrap(from).iso_code, Currency.wrap(to).iso_code, rate)
|
159
172
|
end
|
160
173
|
|
161
|
-
# Retrieve the rate for the given currencies.
|
174
|
+
# Retrieve the rate for the given currencies.
|
162
175
|
# data access.
|
176
|
+
# Delegates to +Money::RatesStore::Memory+
|
163
177
|
#
|
164
178
|
# @param [Currency, String, Symbol] from Currency to exchange from.
|
165
179
|
# @param [Currency, String, Symbol] to Currency to exchange to.
|
166
|
-
# @param [Hash] opts Options hash to set special parameters
|
167
|
-
# @option opts [Boolean] :without_mutex disables the usage of a mutex
|
180
|
+
# @param [Hash] opts Options hash to set special parameters. Backwards compatibility only.
|
168
181
|
#
|
169
182
|
# @return [Numeric]
|
170
183
|
#
|
@@ -176,12 +189,7 @@ class Money
|
|
176
189
|
# bank.get_rate("USD", "CAD") #=> 1.24515
|
177
190
|
# bank.get_rate("CAD", "USD") #=> 0.803115
|
178
191
|
def get_rate(from, to, opts = {})
|
179
|
-
|
180
|
-
if opts[:without_mutex]
|
181
|
-
fn.call
|
182
|
-
else
|
183
|
-
@mutex.synchronize { fn.call }
|
184
|
-
end
|
192
|
+
store.get_rate(Currency.wrap(from).iso_code, Currency.wrap(to).iso_code)
|
185
193
|
end
|
186
194
|
|
187
195
|
# Return the known rates as a string in the format specified. If +file+
|
@@ -190,8 +198,7 @@ class Money
|
|
190
198
|
#
|
191
199
|
# @param [Symbol] format Request format for the resulting string.
|
192
200
|
# @param [String] file Optional file location to write the rates to.
|
193
|
-
# @param [Hash] opts Options hash to set special parameters
|
194
|
-
# @option opts [Boolean] :without_mutex disables the usage of a mutex
|
201
|
+
# @param [Hash] opts Options hash to set special parameters. Backwards compatibility only.
|
195
202
|
#
|
196
203
|
# @return [String]
|
197
204
|
#
|
@@ -208,36 +215,38 @@ class Money
|
|
208
215
|
raise Money::Bank::UnknownRateFormat unless
|
209
216
|
RATE_FORMATS.include? format
|
210
217
|
|
211
|
-
|
212
|
-
fn = -> {
|
218
|
+
store.transaction do
|
213
219
|
s = case format
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
220
|
+
when :json
|
221
|
+
JSON.dump(rates)
|
222
|
+
when :ruby
|
223
|
+
Marshal.dump(rates)
|
224
|
+
when :yaml
|
225
|
+
YAML.dump(rates)
|
226
|
+
end
|
221
227
|
|
222
228
|
unless file.nil?
|
223
229
|
File.open(file, "w") {|f| f.write(s) }
|
224
230
|
end
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
231
|
+
|
232
|
+
s
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
# This should be deprecated.
|
237
|
+
def rates
|
238
|
+
store.each_rate.each_with_object({}) do |(from,to,rate),hash|
|
239
|
+
hash[[from, to].join(SERIALIZER_SEPARATOR)] = rate
|
230
240
|
end
|
231
|
-
s
|
232
241
|
end
|
233
242
|
|
234
243
|
# Loads rates provided in +s+ given the specified format. Available
|
235
244
|
# formats are +:json+, +:ruby+ and +:yaml+.
|
245
|
+
# Delegates to +Money::RatesStore::Memory+
|
236
246
|
#
|
237
247
|
# @param [Symbol] format The format of +s+.
|
238
248
|
# @param [String] s The rates string.
|
239
|
-
# @param [Hash] opts Options hash to set special parameters
|
240
|
-
# @option opts [Boolean] :without_mutex disables the usage of a mutex
|
249
|
+
# @param [Hash] opts Options hash to set special parameters. Backwards compatibility only.
|
241
250
|
#
|
242
251
|
# @return [self]
|
243
252
|
#
|
@@ -254,37 +263,23 @@ class Money
|
|
254
263
|
raise Money::Bank::UnknownRateFormat unless
|
255
264
|
RATE_FORMATS.include? format
|
256
265
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
}
|
267
|
-
if opts[:without_mutex]
|
268
|
-
fn.call
|
269
|
-
else
|
270
|
-
@mutex.synchronize { fn.call }
|
271
|
-
end
|
272
|
-
self
|
273
|
-
end
|
266
|
+
store.transaction do
|
267
|
+
data = case format
|
268
|
+
when :json
|
269
|
+
JSON.load(s)
|
270
|
+
when :ruby
|
271
|
+
Marshal.load(s)
|
272
|
+
when :yaml
|
273
|
+
YAML.load(s)
|
274
|
+
end
|
274
275
|
|
275
|
-
|
276
|
+
data.each do |key, rate|
|
277
|
+
from, to = key.split(SERIALIZER_SEPARATOR)
|
278
|
+
store.add_rate from, to, rate
|
279
|
+
end
|
280
|
+
end
|
276
281
|
|
277
|
-
|
278
|
-
#
|
279
|
-
# @param [Currency, String, Symbol] from The currency to exchange from.
|
280
|
-
# @param [Currency, String, Symbol] to The currency to exchange to.
|
281
|
-
#
|
282
|
-
# @return [String]
|
283
|
-
#
|
284
|
-
# @example
|
285
|
-
# rate_key_for("USD", "CAD") #=> "USD_TO_CAD"
|
286
|
-
def rate_key_for(from, to)
|
287
|
-
"#{Currency.wrap(from).iso_code}_TO_#{Currency.wrap(to).iso_code}".upcase
|
282
|
+
self
|
288
283
|
end
|
289
284
|
end
|
290
285
|
end
|