exchange 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.gitignore +1 -0
  2. data/.rspec +1 -1
  3. data/Gemfile.lock +3 -3
  4. data/README.rdoc +115 -47
  5. data/benchmark/benchmark.rb +49 -0
  6. data/changelog.rdoc +8 -1
  7. data/lib/exchange.rb +4 -4
  8. data/lib/exchange/base.rb +1 -1
  9. data/lib/exchange/cache.rb +2 -0
  10. data/lib/exchange/cache/base.rb +20 -6
  11. data/lib/exchange/cache/configuration.rb +24 -0
  12. data/lib/exchange/cache/file.rb +24 -9
  13. data/lib/exchange/cache/memcached.rb +3 -3
  14. data/lib/exchange/cache/memory.rb +89 -0
  15. data/lib/exchange/cache/rails.rb +1 -1
  16. data/lib/exchange/cache/redis.rb +4 -4
  17. data/lib/exchange/configurable.rb +53 -0
  18. data/lib/exchange/configuration.rb +32 -26
  19. data/lib/exchange/core_extensions.rb +3 -0
  20. data/lib/exchange/core_extensions/cachify.rb +25 -0
  21. data/lib/exchange/core_extensions/float/error_safe.rb +25 -0
  22. data/lib/{core_extensions → exchange/core_extensions/numeric}/conversability.rb +12 -12
  23. data/lib/exchange/external_api.rb +2 -1
  24. data/lib/exchange/external_api/base.rb +34 -9
  25. data/lib/exchange/external_api/call.rb +6 -8
  26. data/lib/exchange/external_api/configuration.rb +25 -0
  27. data/lib/exchange/external_api/ecb.rb +16 -25
  28. data/lib/exchange/external_api/json.rb +11 -1
  29. data/lib/exchange/external_api/open_exchange_rates.rb +65 -0
  30. data/lib/exchange/external_api/xavier_media.rb +7 -7
  31. data/lib/exchange/iso_4217.rb +32 -5
  32. data/lib/exchange/{currency.rb → money.rb} +112 -110
  33. data/lib/exchange/typecasting.rb +94 -0
  34. data/spec/exchange/cache/base_spec.rb +2 -2
  35. data/spec/exchange/cache/configuration_spec.rb +56 -0
  36. data/spec/exchange/cache/file_spec.rb +10 -8
  37. data/spec/exchange/cache/memcached_spec.rb +9 -18
  38. data/spec/exchange/cache/memory_spec.rb +122 -0
  39. data/spec/exchange/cache/no_cache_spec.rb +5 -15
  40. data/spec/exchange/cache/rails_spec.rb +2 -6
  41. data/spec/exchange/cache/redis_spec.rb +8 -18
  42. data/spec/exchange/configuration_spec.rb +31 -7
  43. data/spec/exchange/core_extensions/array/cachify_spec.rb +12 -0
  44. data/spec/exchange/core_extensions/float/error_safe_spec.rb +49 -0
  45. data/spec/exchange/core_extensions/hash/cachify_spec.rb +12 -0
  46. data/spec/exchange/core_extensions/numeric/cachify_spec.rb +26 -0
  47. data/spec/{core_extensions → exchange/core_extensions/numeric}/conversability_spec.rb +22 -22
  48. data/spec/exchange/core_extensions/string/cachify_spec.rb +59 -0
  49. data/spec/exchange/core_extensions/symbol/cachify_spec.rb +12 -0
  50. data/spec/exchange/external_api/base_spec.rb +10 -7
  51. data/spec/exchange/external_api/call_spec.rb +3 -0
  52. data/spec/exchange/external_api/configuration_spec.rb +52 -0
  53. data/spec/exchange/external_api/ecb_spec.rb +8 -5
  54. data/spec/exchange/external_api/open_exchange_rates_spec.rb +70 -0
  55. data/spec/exchange/external_api/xavier_media_spec.rb +8 -5
  56. data/spec/exchange/iso_4217_spec.rb +208 -20
  57. data/spec/exchange/{currency_spec.rb → money_spec.rb} +102 -82
  58. data/spec/exchange/typecasting_spec.rb +86 -0
  59. metadata +117 -71
  60. data/exchange-0.7.5.gem +0 -0
  61. data/exchange-0.7.6.gem +0 -0
  62. data/lib/exchange/external_api/currency_bot.rb +0 -61
  63. data/spec/exchange/external_api/currency_bot_spec.rb +0 -63
data/.gitignore CHANGED
@@ -13,6 +13,7 @@ doc
13
13
 
14
14
  # bundler
15
15
  .bundle
16
+ *.rdb
16
17
 
17
18
  # filestore
18
19
  exchange_filestore
data/.rspec CHANGED
@@ -1,2 +1,2 @@
1
1
  --color
2
- --format documentation
2
+ --format progress
data/Gemfile.lock CHANGED
@@ -1,13 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- exchange (0.7.6)
4
+ exchange (0.9.0)
5
5
  json (>= 1.0.0)
6
6
 
7
7
  GEM
8
8
  remote: http://rubygems.org/
9
9
  specs:
10
- dalli (2.2.1)
10
+ dalli (2.3.0)
11
11
  diff-lcs (1.1.3)
12
12
  json (1.7.5)
13
13
  nokogiri (1.5.5)
@@ -21,7 +21,7 @@ GEM
21
21
  rspec-expectations (2.11.3)
22
22
  diff-lcs (~> 1.1.3)
23
23
  rspec-mocks (2.11.3)
24
- yard (0.8.2.1)
24
+ yard (0.8.3)
25
25
 
26
26
  PLATFORMS
27
27
  java
data/README.rdoc CHANGED
@@ -4,6 +4,16 @@ The Exchange Gem gives you easy access to currency functions directly on your Nu
4
4
 
5
5
  You can use it with just plain ruby projects, in Rails 2 and 3, Sinatra or whatever Framework you like.
6
6
 
7
+ == Installation
8
+ === Bundler / Rails
9
+ Add it to your Gemfile
10
+ gem "exchange", ">=0.8.0"
11
+ === Manually
12
+ Just install it as a gem
13
+ gem install exchange
14
+ Then require it
15
+ require 'exchange'
16
+
7
17
  == Features
8
18
 
9
19
  === Easy Conversion
@@ -12,6 +22,63 @@ Conversion of currencies does not get any easier
12
22
  1.eur.to_usd
13
23
  or better for historic dates
14
24
  1.eur.to_usd(:at => Time.now - 84600)
25
+
26
+
27
+ === Precise Calculation
28
+
29
+ You may know the deal: Floating Point Errors can cost you money:
30
+
31
+ (0.29 * 50).round #=> 14, which is incorrect
32
+
33
+ Whereas
34
+
35
+ (BigDecimal("0.29") * 50).round #=> 15, which is correct
36
+
37
+ Exchange uses BigDecimal in all its currency and conversion operations, so you will not be a likely victim for floating point inaccuracies. It even does implicitly convert counterparts of basic operations like (* / - +) to calculate your values safely:
38
+
39
+ (50.usd * 0.29).round 0 #=> "USD 15.00"
40
+ (0.29 * 50.usd).round 0 #=> 15
41
+
42
+ === BigDecimal? Sounds slow to me
43
+
44
+ If performance combined with conversion is your concern, {head over to this benchmark}[https://github.com/beatrichartz/exchange/blob/master/benchmark/benchmark.rb]. With ruby 1.9.3, you'll get about the following results
45
+
46
+ 1000 operations
47
+
48
+ Normal Float Operation takes 0.000196s
49
+ Big Decimal Operation takes 0.001239s
50
+ Money gem Operation takes 0.05348s
51
+ Exchange gem Operation takes 0.035287s
52
+
53
+ You're right that Big Decimal is slower than Float operations, but then again, the exchange gem outscores the money gem.
54
+
55
+ === A mixin for typecasting
56
+
57
+ There may be a need for you to typecast an attribute of an object as money. Exchange features a typecasting mixin, which you can use with Rails, Ohm, Datamapper, or just plain ruby classes to typecast an attribute as money. Use it like this:
58
+
59
+ class Article
60
+ # make the class method available
61
+ #
62
+ extend Exchange::Typecasting
63
+
64
+ # Install the typecasting for price
65
+ #
66
+ money :price, :currency => :currency
67
+
68
+ # let's say you have currency set in a unique place
69
+ #
70
+ def currency
71
+ manager.currency
72
+ end
73
+ end
74
+
75
+ Now you're able to do this:
76
+
77
+ article = Article.new
78
+ article.price #=> will give you money in the currency defined on the manager
79
+ article.price = 3.45.usd #Will implicitly convert the price if manager.currency is not :usd
80
+
81
+ You can feed the currency option with a proc or a symbol representing the method. For in-depth information about typecasting {visit the documentation here}[http://rubydoc.info/github/beatrichartz/exchange/Exchange/Typecasting]
15
82
 
16
83
  === Only one request per day to keep you up to date
17
84
 
@@ -21,11 +88,9 @@ You're hitting the internet only daily to get new rates (hourly updates are avai
21
88
  On of the issues with currencies is: You never know the format they should be in. With Exchange, you can just use the currencies
22
89
  to_s method, which takes care of the right format for you. You can either have a string with the currency code in front, or just the amount in the right format
23
90
 
24
- Exchange::Currency.new(49.567, :usd).to_s #=> "USD 49.57"
25
- Exchange::Currency.new(45, :jpy).to_s #=> "JPY 45"
26
- Exchange::Currency.new(34.34, :omr).to_s #=> "OMR 34.340"
27
- Exchange::ISO4217.stringif(34.34, :omr).to_s(:iso) #=> "34.340"
28
-
91
+ 49.567.usd.to_s #=> "USD 49.57"
92
+ 45.jpy.to_s #=> "JPY 45"
93
+ 34.34.omr.to_s #=> "OMR 34.340"
29
94
 
30
95
  === Use three great APIs or your own
31
96
 
@@ -33,7 +98,7 @@ Three open APIs are already included:
33
98
 
34
99
  - {Xaviermedia}[http://www.xavierforum.com/viewtopic.php?f=5&t=10979&sid=671a685edbfa5dbec219fbc6793d5057]
35
100
  - {European Central Bank}[http://www.ecb.int/stats/exchange/eurofxref/html/index.en.html]
36
- - {Currency Bot}[http://currencybot.github.com/]
101
+ - {Open Exchange Rates}[http://openexchangerates.org/] (Look for the free plan at the bottom of the page)
37
102
 
38
103
  but if you have another API you like to use, it becomes as easy as writing one Class and two methods to use it.
39
104
  {Example of a custom API Extension}[http://rubydoc.info/github/beatrichartz/exchange/Exchange/ExternalAPI]
@@ -49,41 +114,31 @@ Use one of three available caching solutions:
49
114
  But, same here, if you don't like any of these or want to use your own caching solution, it is as easy as writing one Class and two methods to use it.
50
115
  {Example of a custom cache extension}[http://rubydoc.info/github/beatrichartz/exchange/Exchange/Cache]
51
116
 
52
- == Installation
53
- === Bundler / Rails
54
- Add it to your Gemfile
55
- gem "exchange", ">=0.7.3"
56
- === Manually
57
- Just install it as a gem
58
- gem install exchange
59
- Then require it
60
- require 'exchange'
61
-
62
117
  == Basic Operations
63
118
 
64
119
  === Convert
65
120
 
66
121
  Converting one currency to another is as easy as 1,2,3. Don't be afraid, even if it returns a currency object, all Fixed and Float operations can be applied as method missing routes to the value
67
122
 
68
- 1.usd.to_eur #=> #<Exchange::Currency @value=0.93 @currency=:eur>
69
- 2.3.dkk.to_sek #=> #<Exchange::Currency @value=3.33 @currency=:sek>
70
- 45.54.nok.to_sek #=> #<Exchange::Currency @value=3.33 @currency=:sek>
123
+ 1.usd.to_eur #=> #<Exchange::Money @value=0.93 @currency=:eur>
124
+ 2.3.dkk.to_sek #=> #<Exchange::Money @value=3.33 @currency=:sek>
125
+ 45.54.nok.to_sek #=> #<Exchange::Money @value=3.33 @currency=:sek>
71
126
 
72
127
  Easily convert one currency to another at a historical rate
73
128
 
74
- 1.52.usd.to_eur :at => '2011-01-01' #=> #<Exchange::Currency @value=1.23 @currency=:eur>
75
- 3.45.eur.to_sek :at => Time.gm(2011,3,3) #=> #<Exchange::Currency @value=19.23 @currency=:sek>
76
- 345.sek.to_nok :at => Time.gm(2011,3,3) #=> #<Exchange::Currency @value=348 @currency=:nok>
129
+ 1.52.usd.to_eur :at => '2011-01-01' #=> #<Exchange::Money @value=1.23 @currency=:eur>
130
+ 3.45.eur.to_sek :at => Time.gm(2011,3,3) #=> #<Exchange::Money @value=19.23 @currency=:sek>
131
+ 345.sek.to_nok :at => Time.gm(2011,3,3) #=> #<Exchange::Money @value=348 @currency=:nok>
77
132
 
78
133
  Or even define an instance of currency as historic by adding a time.
79
134
 
80
- 1.52.usd(:at => '2011-01-01').to_eur #=> #<Exchange::Currency @value=1.23 @currency=:eur>
81
- 3.45.eur(:at => Time.gm(2011,3,3)).to_sek #=> #<Exchange::Currency @value=19.23 @currency=:sek>
82
- 345.sek(:at => Time.gm(2011,3,3)).to_nok #=> #<Exchange::Currency @value=348 @currency=:nok>
135
+ 1.52.usd(:at => '2011-01-01').to_eur #=> #<Exchange::Money @value=1.23 @currency=:eur>
136
+ 3.45.eur(:at => Time.gm(2011,3,3)).to_sek #=> #<Exchange::Money @value=19.23 @currency=:sek>
137
+ 345.sek(:at => Time.gm(2011,3,3)).to_nok #=> #<Exchange::Money @value=348 @currency=:nok>
83
138
 
84
139
  Do multiple conversion steps at once (if in any way useful)
85
140
 
86
- 3.chf.to_eur(:at => '2011-02-04').to_usd #=> #<Exchange::Currency @value=5.3 @currency=:eur>
141
+ 3.chf.to_eur(:at => '2011-02-04').to_usd #=> #<Exchange::Money @value=5.3 @currency=:eur>
87
142
 
88
143
 
89
144
  === Compare
@@ -99,49 +154,54 @@ Compare Currencies, they will convert implicitly
99
154
 
100
155
  Sort multiple currencies at once
101
156
 
102
- [5.eur, 4.usd, 4.chf(:at => '2010-01-01')].sort #=> [#<Exchange::Currency @value=4 @currency=:usd>, #<Exchange::Currency @value=4 @currency=:chf>, #<Exchange::Currency @value=5 @currency=:eur>]
157
+ [5.eur, 4.usd, 4.chf(:at => '2010-01-01')].sort #=> [#<Exchange::Money @value=4 @currency=:usd>, #<Exchange::Money @value=4 @currency=:chf>, #<Exchange::Money @value=5 @currency=:eur>]
103
158
 
104
159
  This is true, because it uses the same historic conversion rate
105
160
 
106
161
  3.eur(:at => '201-01-01').to_usd == 3.eur.to_usd(:at => '201-01-01')
107
162
 
108
- But this is false, obviously, because the second instance uses the present exchange rate
163
+ But this is false, obviously, because the second instance uses the present exchange rate which differs from the historic one (if the two rates match, this will be true again)
109
164
 
110
- 3.eur(:at => '201-01-01').to_usd == 3.eur.to_usd
165
+ 3.eur(:at => '2001-01-01').to_usd == 3.eur.to_usd
111
166
 
112
167
  === Operate
113
168
 
114
169
  Add, Subtract, Multiply, Divide Currencies and don't lose a dime. The result will get returned in the currency of the first argument
115
170
 
116
- 1.usd + 1.32.eur #=> #<Exchange::Currency @value=2.54 @currency=:usd>
117
- 1.usd - 1.32.eur #=> #<Exchange::Currency @value=-0.2 @currency=:usd>
118
- 1.usd * 1.32.eur #=> #<Exchange::Currency @value=3.44 @currency=:usd>
119
- 1.usd / 1.32.eur #=> #<Exchange::Currency @value=0.89 @currency=:usd>
171
+ 1.usd + 1.32.eur #=> #<Exchange::Money @value=2.54 @currency=:usd>
172
+ 1.usd - 1.32.eur #=> #<Exchange::Money @value=-0.2 @currency=:usd>
173
+ 1.usd * 1.32.eur #=> #<Exchange::Money @value=3.44 @currency=:usd>
174
+ 1.usd / 1.32.eur #=> #<Exchange::Money @value=0.89 @currency=:usd>
120
175
 
121
176
 
122
177
  If you define a currency object as historic. It will use historic conversion if it gets converted (in this example, the 1.32 eur will get converted to usd at the rate of January 1 2008)
123
178
 
124
- 1.usd - 1.32.eur(:at => '2008-1-1') #=> #<Exchange::Currency @value=2.54 @currency=:usd>
179
+ 1.usd - 1.32.eur(:at => '2008-1-1') #=> #<Exchange::Money @value=2.54 @currency=:usd>
180
+
181
+ You can just instantiate currencies and apply operations. Rounding will by default round the currency to its ISO4217 decimal precision:
125
182
 
126
- You can just instantiate currencies and apply operations
183
+ 3.123.eur.round #=> #<Exchange::Money @value=3.12 @currency=:eur>
184
+
185
+ You can also pass the precision you wish for as an argument, round, ceil, floor act like normal:
127
186
 
128
- 3.1.eur.round #=> #<Exchange::Currency @value=3 @currency=:eur>
187
+ 3.1234.eur.round(0) #=> #<Exchange::Money @value=3 @currency=:eur>
129
188
 
130
189
  Convert one currency to another and round, ceil or floor it, it still retains currency information of the actual and previous currency
131
190
 
132
- 1.34.usd.to_eur.round #=> #<Exchange::Currency @value=1 @currency=:eur>
133
- 10.34.usd.to_nok.ceil #=> #<Exchange::Currency @value=45 @currency=:nok>
134
- 5.34.usd.to_eur.floor #=> #<Exchange::Currency @value=4 @currency=:eur>
135
- 5.34.usd.to_eur.floor.from #=> #<Exchange::Currency @value=5.34 @currency=:usd>
191
+ 1.34.usd.to_eur.round(0) #=> #<Exchange::Money @value=1 @currency=:eur>
192
+ 10.34.usd.to_nok.ceil(0) #=> #<Exchange::Money @value=45 @currency=:nok>
193
+ 5.34.usd.to_eur.floor(0) #=> #<Exchange::Money @value=4 @currency=:eur>
194
+ 5.34.usd.to_eur.floor.from #=> #<Exchange::Money @value=5.34 @currency=:usd>
136
195
 
137
196
 
138
197
  === Retain Information
139
198
 
140
199
  Access the original currency and its value after conversion, even over multiple steps
141
- converted = 2.eur.to_usd #=> #<Exchange::Currency @value=2.12 @currency=:usd>
142
- converted.from #=> #<Exchange::Currency @value=2 @currency=:eur>
143
- converted2 = converted.to_nok #=> #<Exchange::Currency @value=22.12 @currency=:nok>
144
- converted2.from #=> #<Exchange::Currency @value=2.12 @currency=:usd>
200
+
201
+ converted = 2.eur.to_usd #=> #<Exchange::Money @value=2.12 @currency=:usd>
202
+ converted.from #=> #<Exchange::Money @value=2 @currency=:eur>
203
+ converted2 = converted.to_nok #=> #<Exchange::Money @value=22.12 @currency=:nok>
204
+ converted2.from #=> #<Exchange::Money @value=2.12 @currency=:usd>
145
205
 
146
206
  == Configuration
147
207
 
@@ -157,7 +217,7 @@ You can configure the exchange gem to a variety of options, allowing you to cont
157
217
  The options available are
158
218
 
159
219
  :cache Takes the cache options as a hash, the options are:
160
- :subclass (default :memcached) The cache subclass to use for caching. Available: Rails cache, Redis, Memcached, Filecache
220
+ :subclass (default :memory) The cache subclass to use for caching. Available: Memory, Rails cache, Redis, Memcached, File
161
221
  :host (default '127.0.0.1') A string with the hostname or IP to set the cache host to. Does not have to be set for Rails cache
162
222
  :port (default 11211) An integer for the cache port. Does not have to be set for Rails cache
163
223
  :expire (default :daily) Which period is used to expire the cache, :daily or :hourly are available
@@ -166,6 +226,7 @@ The options available are
166
226
  :subclass (default :xavier_media) The api to use. Available: Xavier Media, ECB, Currency Bot
167
227
  :retries (default 5) The number of times the gem should retry to connect to the api host
168
228
  :app_id (default nil) The app id to use with your api request
229
+ :protocol (default :http) The protocol to use with the request
169
230
 
170
231
  :allow_mixed_opterations (default true) If set to false, Operations with with different currencies raise errors.
171
232
 
@@ -209,10 +270,17 @@ Use the Xaviermedia API as the source of your conversion rates
209
270
  }
210
271
  end
211
272
 
212
- Use the currencybot Open Source API as a source of your conversion rates
273
+ Use the open exchange rates Open Source API as a source of your conversion rates
274
+ Exchange.configuration = Exchange::Configuration.new do |c|
275
+ c.api = {
276
+ :subclass => :open_exchange_rates
277
+ }
278
+ end
279
+
280
+ Use https as request protocol of your api requests:
213
281
  Exchange.configuration = Exchange::Configuration.new do |c|
214
282
  c.api = {
215
- :subclass => :currency_bot
283
+ :protocol => :https
216
284
  }
217
285
  end
218
286
 
@@ -0,0 +1,49 @@
1
+ require 'benchmark'
2
+ require 'bigdecimal'
3
+
4
+ class Helper
5
+ def load_or_omit a_gem
6
+ begin
7
+ require a_gem.to_s
8
+ return true
9
+ rescue LoadError => e
10
+ puts "You do not have #{a_gem} installed. gem install #{a_gem} to benchmark it\n\n"
11
+ return false
12
+ end
13
+ end
14
+
15
+ def median array
16
+ (array.inject(0) { |sum, member| sum += member } / 3.0).round 6 if array
17
+ end
18
+ end
19
+
20
+ helper = Helper.new
21
+
22
+ operations = 1000
23
+ results = {}
24
+
25
+ results[:normal_float] = []
26
+ 3.times { results[:normal_float] << Benchmark.realtime { operations.times { 3.555 * 4.234 } } }
27
+
28
+ results[:big_decimal] = []
29
+ one = BigDecimal.new("3.555")
30
+ two = BigDecimal.new("4.234")
31
+ 3.times { results[:big_decimal] << Benchmark.realtime { operations.times { one * two } } }
32
+
33
+ if helper.load_or_omit(:money)
34
+ Money.add_rate("USD", "CAD", 1.24515)
35
+ results[:money] = []
36
+ 3.times { results[:money] << Benchmark.realtime { operations.times { Money.us_dollar(50) * 0.29 } } }
37
+ end
38
+
39
+ if helper.load_or_omit(:exchange)
40
+ 1.usd.to_cad #make the rate available in memory
41
+ results[:exchange] = []
42
+ 3.times { results[:exchange] << Benchmark.realtime { operations.times { 50.usd * 0.29 } } }
43
+ end
44
+
45
+ puts "#{operations} operations\n\n"
46
+ puts "Normal Float Operation takes \t#{helper.median(results[:normal_float])}s\n"
47
+ puts "Big Decimal Operation takes \t#{helper.median(results[:big_decimal])}s\n"
48
+ puts "Money gem Operation takes \t#{helper.median(results[:money])}s\n" if results[:money]
49
+ puts "Exchange gem Operation takes \t#{helper.median(results[:exchange])}s\n" if results[:exchange]
data/changelog.rdoc CHANGED
@@ -1,7 +1,14 @@
1
1
  = Changes to Exchange
2
2
 
3
- == 0.7.3
3
+ == 0.9.0
4
+ - added memory cache support as the new default. This allows you to cache without any external requirement, directly in ruby.
5
+ - Added a typecasting helper for money to exchange. This allows you to typecast any given attribute into a instance of Exchange::Money
6
+ - made the base operations more floating point error save. Now even when you use a float with exchange, it will convert it to bigdecimal before doing base calculations (* / + -) in both ways. This does not mean you will not encounter any floating point errors, but it makes it highly unlikely.
7
+ - improved performance quite a bit on the conversion methods. Exchange now beats every other known gem for currency conversion in conversion speed
8
+
9
+ == 0.8.0
4
10
  - jruby compatibility, horray!
11
+ - readded json as an explicit dependency since its used in cache and api
5
12
 
6
13
  == 0.7.1
7
14
  - The DSL is now included into Numeric, which makes currency operations available for all subclasses (including your own) of Numeric
data/lib/exchange.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  require 'rubygems'
2
2
  require 'bigdecimal'
3
3
  require 'open-uri'
4
- require 'ostruct'
5
- require 'json'
6
4
  require 'exchange/base'
5
+ require 'exchange/configurable'
7
6
  require 'exchange/gem_loader'
8
7
  require 'exchange/helper'
9
8
  require 'exchange/iso_4217'
10
- require 'exchange/currency'
9
+ require 'exchange/money'
11
10
  require 'exchange/external_api'
12
11
  require 'exchange/cache'
13
12
  require 'exchange/configuration'
14
- require 'core_extensions/conversability'
13
+ require 'exchange/core_extensions'
14
+ require 'exchange/typecasting'
data/lib/exchange/base.rb CHANGED
@@ -2,7 +2,7 @@ module Exchange
2
2
 
3
3
  # The current version of the exchange gem
4
4
  #
5
- VERSION = '0.8.0'
5
+ VERSION = '0.9.0'
6
6
 
7
7
  # The root installation path of the gem
8
8
  # @version 0.5
@@ -1,5 +1,7 @@
1
+ require 'exchange/cache/configuration'
1
2
  require 'exchange/cache/base'
2
3
  require 'exchange/cache/memcached'
4
+ require 'exchange/cache/memory'
3
5
  require 'exchange/cache/redis'
4
6
  require 'exchange/cache/rails'
5
7
  require 'exchange/cache/file'
@@ -60,22 +60,36 @@ module Exchange
60
60
 
61
61
  # A Cache Key generator for the API Classes and the time
62
62
  # Generates a key which can handle expiration by itself
63
- # @param [Exchange::ExternalAPI::Subclass] api_class The API to store the data for
64
- # @param [optional, Time] time The time for which the data is valid
63
+ # @param [Exchange::ExternalAPI::Subclass] api The API to store the data for
64
+ # @param [Hash] opts The options for caching
65
65
  # @return [String] A string that can be used as cache key
66
66
  # @example
67
- # Exchange::Cache::Base.key(Exchange::ExternalAPI::CurrencyBot, Time.gm(2012,1,1)) #=> "Exchange_ExternalAPI_CurrencyBot_2012_1"
67
+ # Exchange::Cache::Base.key(Exchange::ExternalAPI::OpenExchangeRates, Time.gm(2012,1,1)) #=> "Exchange_ExternalAPI_CurrencyBot_2012_1"
68
68
  #
69
69
  def key api, opts={}
70
- time = Exchange::Helper.assure_time(opts[:at], :default => :now)
71
- [ 'exchange',
70
+ time = helper.assure_time(opts[:at], :default => :now)
71
+ ['exchange',
72
72
  api.to_s,
73
73
  time.year.to_s,
74
74
  time.yday.to_s,
75
- Exchange.configuration.cache.expire == :hourly ? time.hour.to_s : nil,
75
+ config.expire == :hourly ? time.hour.to_s : nil,
76
76
  *(opts[:key_for] || [])
77
77
  ].compact.join('_')
78
78
  end
79
+
80
+ # Convenience accessor to get to the cache configuration
81
+ # @return [Exchange::Cache::Configuration] the current cache configuration
82
+ #
83
+ def config
84
+ Exchange.configuration.cache
85
+ end
86
+
87
+ # Convenience accessor for the helper
88
+ # @return [Exchange::Helper] the helper class
89
+ #
90
+ def helper
91
+ @helper ||= Exchange::Helper
92
+ end
79
93
 
80
94
  end
81
95