money 6.5.1 → 6.6.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.
- 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
|