exchange 0.8.0 → 0.9.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.
- data/.gitignore +1 -0
- data/.rspec +1 -1
- data/Gemfile.lock +3 -3
- data/README.rdoc +115 -47
- data/benchmark/benchmark.rb +49 -0
- data/changelog.rdoc +8 -1
- data/lib/exchange.rb +4 -4
- data/lib/exchange/base.rb +1 -1
- data/lib/exchange/cache.rb +2 -0
- data/lib/exchange/cache/base.rb +20 -6
- data/lib/exchange/cache/configuration.rb +24 -0
- data/lib/exchange/cache/file.rb +24 -9
- data/lib/exchange/cache/memcached.rb +3 -3
- data/lib/exchange/cache/memory.rb +89 -0
- data/lib/exchange/cache/rails.rb +1 -1
- data/lib/exchange/cache/redis.rb +4 -4
- data/lib/exchange/configurable.rb +53 -0
- data/lib/exchange/configuration.rb +32 -26
- data/lib/exchange/core_extensions.rb +3 -0
- data/lib/exchange/core_extensions/cachify.rb +25 -0
- data/lib/exchange/core_extensions/float/error_safe.rb +25 -0
- data/lib/{core_extensions → exchange/core_extensions/numeric}/conversability.rb +12 -12
- data/lib/exchange/external_api.rb +2 -1
- data/lib/exchange/external_api/base.rb +34 -9
- data/lib/exchange/external_api/call.rb +6 -8
- data/lib/exchange/external_api/configuration.rb +25 -0
- data/lib/exchange/external_api/ecb.rb +16 -25
- data/lib/exchange/external_api/json.rb +11 -1
- data/lib/exchange/external_api/open_exchange_rates.rb +65 -0
- data/lib/exchange/external_api/xavier_media.rb +7 -7
- data/lib/exchange/iso_4217.rb +32 -5
- data/lib/exchange/{currency.rb → money.rb} +112 -110
- data/lib/exchange/typecasting.rb +94 -0
- data/spec/exchange/cache/base_spec.rb +2 -2
- data/spec/exchange/cache/configuration_spec.rb +56 -0
- data/spec/exchange/cache/file_spec.rb +10 -8
- data/spec/exchange/cache/memcached_spec.rb +9 -18
- data/spec/exchange/cache/memory_spec.rb +122 -0
- data/spec/exchange/cache/no_cache_spec.rb +5 -15
- data/spec/exchange/cache/rails_spec.rb +2 -6
- data/spec/exchange/cache/redis_spec.rb +8 -18
- data/spec/exchange/configuration_spec.rb +31 -7
- data/spec/exchange/core_extensions/array/cachify_spec.rb +12 -0
- data/spec/exchange/core_extensions/float/error_safe_spec.rb +49 -0
- data/spec/exchange/core_extensions/hash/cachify_spec.rb +12 -0
- data/spec/exchange/core_extensions/numeric/cachify_spec.rb +26 -0
- data/spec/{core_extensions → exchange/core_extensions/numeric}/conversability_spec.rb +22 -22
- data/spec/exchange/core_extensions/string/cachify_spec.rb +59 -0
- data/spec/exchange/core_extensions/symbol/cachify_spec.rb +12 -0
- data/spec/exchange/external_api/base_spec.rb +10 -7
- data/spec/exchange/external_api/call_spec.rb +3 -0
- data/spec/exchange/external_api/configuration_spec.rb +52 -0
- data/spec/exchange/external_api/ecb_spec.rb +8 -5
- data/spec/exchange/external_api/open_exchange_rates_spec.rb +70 -0
- data/spec/exchange/external_api/xavier_media_spec.rb +8 -5
- data/spec/exchange/iso_4217_spec.rb +208 -20
- data/spec/exchange/{currency_spec.rb → money_spec.rb} +102 -82
- data/spec/exchange/typecasting_spec.rb +86 -0
- metadata +117 -71
- data/exchange-0.7.5.gem +0 -0
- data/exchange-0.7.6.gem +0 -0
- data/lib/exchange/external_api/currency_bot.rb +0 -61
- data/spec/exchange/external_api/currency_bot_spec.rb +0 -63
@@ -1,34 +1,31 @@
|
|
1
1
|
# Top Level Module of the the gem.
|
2
2
|
# @author Beat Richartz
|
3
|
-
# @version 0.
|
3
|
+
# @version 0.9
|
4
4
|
# @since 0.1
|
5
5
|
|
6
6
|
module Exchange
|
7
7
|
# @author Beat Richartz
|
8
|
-
#
|
8
|
+
# Money Objects instantiated from the money class can be used for basic mathematical operations and currency conversions
|
9
9
|
# @version 0.1
|
10
10
|
# @since 0.1
|
11
11
|
#
|
12
|
-
class
|
12
|
+
class Money
|
13
13
|
include Comparable
|
14
14
|
|
15
|
-
# @
|
16
|
-
# @return [BigDecimal] number The number the currency object has been instantiated from
|
15
|
+
# @return [BigDecimal] number The number the money object has been instantiated from
|
17
16
|
#
|
18
|
-
|
17
|
+
attr_accessor :value
|
19
18
|
|
20
|
-
# @
|
21
|
-
# @return [Symbol, String] currency the currency of the currency object
|
19
|
+
# @return [Symbol, String] currency the currency of the money object
|
22
20
|
#
|
23
|
-
|
21
|
+
attr_accessor :currency
|
24
22
|
|
25
|
-
# @attr_reader
|
26
23
|
# @return [Time] The time at which the conversion has taken place or should take place if the object is involved in operations
|
27
24
|
#
|
28
|
-
|
25
|
+
attr_accessor :time
|
29
26
|
|
30
27
|
# @attr_reader
|
31
|
-
# @return [Exchange::
|
28
|
+
# @return [Exchange::Money] The original money object this money object was converted from
|
32
29
|
#
|
33
30
|
attr_reader :from
|
34
31
|
|
@@ -37,60 +34,65 @@ module Exchange
|
|
37
34
|
attr_reader :api
|
38
35
|
|
39
36
|
# Intialize the currency with a number and a currency
|
40
|
-
# @param [Integer, Float]
|
41
|
-
# @param [
|
37
|
+
# @param [Integer, Float] value The number the currency is instantiated from
|
38
|
+
# @param [Symbol] currency_arg The currency the money object is in as a downcased symbol
|
42
39
|
# @param [Hash] opts Optional Parameters for instantiation
|
43
40
|
# @option opts [Time] :at The time at which conversion took place
|
44
|
-
# @option opts [String,Symbol] :from The
|
41
|
+
# @option opts [String,Symbol] :from The money object this money object was converted from
|
45
42
|
# @version 0.2
|
46
43
|
#
|
47
|
-
# @example Instantiate a
|
48
|
-
# Exchange::
|
49
|
-
# #=> #<Exchange::
|
50
|
-
# @example Instantiate a
|
51
|
-
# Exchange::
|
52
|
-
# #=> #<Exchange::
|
44
|
+
# @example Instantiate a money object of 40 US Dollars
|
45
|
+
# Exchange::Money.new(40, :usd)
|
46
|
+
# #=> #<Exchange::Money @number=40.0 @currency=:usd @time=#<Time>>
|
47
|
+
# @example Instantiate a money object of 40 US Dollars and convert it to Euro. It shows the conversion date and the original currency
|
48
|
+
# Exchange::Money.new(40, :usd).to_eur(:at => Time.gm(2012,9,1))
|
49
|
+
# #=> #<Exchange::Money @number=37.0 @currency=:usd @time=#<Time> @from=#<Exchange::Money @number=40.0 @currency=:usd>>
|
53
50
|
#
|
54
|
-
def initialize value,
|
55
|
-
@value = ISO4217.instantiate(value, currency)
|
56
|
-
@currency = currency
|
57
|
-
@time = Helper.assure_time(opts[:at], :default => :now)
|
51
|
+
def initialize value, currency_arg=nil, opts={}, &block
|
58
52
|
@from = opts[:from]
|
59
53
|
@api = Exchange.configuration.api.subclass
|
54
|
+
|
55
|
+
yield(self) if block_given?
|
56
|
+
|
57
|
+
self.time = Helper.assure_time(time || opts[:at], :default => :now)
|
58
|
+
self.value = ISO4217.instantiate(value, currency || currency_arg)
|
59
|
+
self.currency = currency || currency_arg
|
60
60
|
end
|
61
61
|
|
62
|
-
# Method missing is used to handle conversions from one
|
62
|
+
# Method missing is used to handle conversions from one money object to another. It only handles currencies which are available in
|
63
63
|
# the API class set in the configuration.
|
64
64
|
# @example Calls convert_to with 'chf'
|
65
|
-
# Exchange::
|
65
|
+
# Exchange::Money.new(40,:usd).to_chf
|
66
66
|
# @example Calls convert_to with 'sek' and :at => Time.gm(2012,2,2)
|
67
|
-
# Exchange::
|
67
|
+
# Exchange::Money.new(40,:nok).to_sek(:at => Time.gm(2012,2,2))
|
68
68
|
#
|
69
69
|
def method_missing method, *args, &block
|
70
|
-
match = method.to_s.match /\Ato_(\w{3})$/
|
71
|
-
currency = $1
|
72
|
-
|
73
|
-
if match && api_supports_currency?(currency)
|
74
|
-
return convert_to currency, { :at => time }.merge(args.first || {})
|
75
|
-
elsif match
|
76
|
-
test_for_no_rate_error(currency)
|
77
|
-
end
|
78
|
-
|
79
70
|
value.send method, *args, &block
|
80
71
|
end
|
81
72
|
|
73
|
+
ISO4217.currencies.each do |c|
|
74
|
+
define_method :"to_#{c}" do |*args|
|
75
|
+
if api_supports_currency?(c)
|
76
|
+
convert_to c, { :at => time }.merge(args.first || {})
|
77
|
+
else
|
78
|
+
raise_no_rate_error(c)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
82
83
|
# Converts this instance of currency into another currency
|
83
|
-
# @return [Exchange::
|
84
|
+
# @return [Exchange::Money] An instance of Exchange::Money with the converted number and the converted currency
|
84
85
|
# @param [Symbol, String] other The currency to convert the number to
|
85
86
|
# @param [Hash] opts An options hash
|
86
87
|
# @option [Time] :at The timestamp of the rate the conversion took place in
|
87
88
|
# @example convert to 'chf'
|
88
|
-
# Exchange::
|
89
|
+
# Exchange::Money.new(40,:usd).convert_to('chf')
|
89
90
|
# @example convert to 'sek' at a specific rate
|
90
|
-
# Exchange::
|
91
|
+
# Exchange::Money.new(40,:nok).convert_to('sek', :at => Time.gm(2012,2,2))
|
91
92
|
#
|
92
93
|
def convert_to other, opts={}
|
93
|
-
|
94
|
+
opts[:from] = self
|
95
|
+
Money.new(api.new.convert(value, currency, other, opts), other, opts)
|
94
96
|
end
|
95
97
|
|
96
98
|
class << self
|
@@ -102,7 +104,7 @@ module Exchange
|
|
102
104
|
#
|
103
105
|
def install_operation op
|
104
106
|
define_method op do |*precision|
|
105
|
-
Exchange::
|
107
|
+
Exchange::Money.new(ISO4217.send(op, self.value, self.currency, precision.first), currency, :at => time, :from => self)
|
106
108
|
end
|
107
109
|
end
|
108
110
|
|
@@ -114,8 +116,8 @@ module Exchange
|
|
114
116
|
self.class_eval <<-EOV
|
115
117
|
def #{op}(other)
|
116
118
|
test_for_currency_mix_error(other)
|
117
|
-
new_value = value #{op} (other.kind_of?(
|
118
|
-
Exchange::
|
119
|
+
new_value = value #{op} (other.kind_of?(Money) ? other.convert_to(self.currency, :at => other.time) : BigDecimal.new(other.to_s))
|
120
|
+
Exchange::Money.new(new_value, currency, :at => time, :from => self)
|
119
121
|
end
|
120
122
|
EOV
|
121
123
|
end
|
@@ -124,126 +126,126 @@ module Exchange
|
|
124
126
|
|
125
127
|
# Round the currency. Since this is a currency, it will round to the standard decimal value.
|
126
128
|
# If you want to round it to another precision, you have to specifically ask for it.
|
127
|
-
# @return [Exchange::
|
129
|
+
# @return [Exchange::Money] The currency you started with with a rounded value
|
128
130
|
# @param [Integer] precision The precision you want the rounding to have. Defaults to the ISO 4217 standard value for the currency
|
129
131
|
# @since 0.1
|
130
132
|
# @version 0.7.1
|
131
133
|
# @example Round your currency to the iso standard number of decimals
|
132
|
-
# Exchange::
|
133
|
-
# #=> #<Exchange::
|
134
|
+
# Exchange::Money.new(40.545, :usd).round
|
135
|
+
# #=> #<Exchange::Money @value=40.55 @currency=:usd>
|
134
136
|
# @example Round your currency to another number of decimals
|
135
|
-
# Exchange::
|
136
|
-
# #=> #<Exchange::
|
137
|
+
# Exchange::Money.new(40.545, :usd).round(0)
|
138
|
+
# #=> #<Exchange::Money @value=41 @currency=:usd>
|
137
139
|
#
|
138
140
|
install_operation :round
|
139
141
|
|
140
142
|
|
141
143
|
# Ceil the currency. Since this is a currency, it will ceil to the standard decimal value.
|
142
144
|
# If you want to ceil it to another precision, you have to specifically ask for it.
|
143
|
-
# @return [Exchange::
|
145
|
+
# @return [Exchange::Money] The currency you started with with a ceiled value
|
144
146
|
# @param [Integer] precision The precision you want the ceiling to have. Defaults to the ISO 4217 standard value for the currency
|
145
147
|
# @since 0.1
|
146
148
|
# @version 0.7.1
|
147
149
|
# @example Ceil your currency to the iso standard number of decimals
|
148
|
-
# Exchange::
|
149
|
-
# #=> #<Exchange::
|
150
|
+
# Exchange::Money.new(40.544, :usd).ceil
|
151
|
+
# #=> #<Exchange::Money @value=40.55 @currency=:usd>
|
150
152
|
# @example Ceil your currency to another number of decimals
|
151
|
-
# Exchange::
|
152
|
-
# #=> #<Exchange::
|
153
|
+
# Exchange::Money.new(40.445, :usd).ceil(0)
|
154
|
+
# #=> #<Exchange::Money @value=41 @currency=:usd>
|
153
155
|
#
|
154
156
|
install_operation :ceil
|
155
157
|
|
156
158
|
|
157
159
|
# Floor the currency. Since this is a currency, it will ceil to the standard decimal value.
|
158
160
|
# If you want to ceil it to another precision, you have to specifically ask for it.
|
159
|
-
# @return [Exchange::
|
161
|
+
# @return [Exchange::Money] The currency you started with with a floored value
|
160
162
|
# @param [Integer] precision The precision you want the flooring to have. Defaults to the ISO 4217 standard value for the currency
|
161
163
|
# @since 0.1
|
162
164
|
# @version 0.7.1
|
163
165
|
# @example Floor your currency to the iso standard number of decimals
|
164
|
-
# Exchange::
|
165
|
-
# #=> #<Exchange::
|
166
|
+
# Exchange::Money.new(40.545, :usd).floor
|
167
|
+
# #=> #<Exchange::Money @value=40.54 @currency=:usd>
|
166
168
|
# @example Floor your currency to another number of decimals
|
167
|
-
# Exchange::
|
168
|
-
# #=> #<Exchange::
|
169
|
+
# Exchange::Money.new(40.545, :usd).floor(0)
|
170
|
+
# #=> #<Exchange::Money @value=40 @currency=:usd>
|
169
171
|
#
|
170
172
|
install_operation :floor
|
171
173
|
|
172
174
|
|
173
175
|
# Add value to the currency
|
174
|
-
# @param [Integer, Float, Exchange::
|
175
|
-
# @return [Exchange::
|
176
|
+
# @param [Integer, Float, Exchange::Money] other The value to be added to the currency. If an Exchange::Money, it is converted to the instance's currency and then the converted value is added.
|
177
|
+
# @return [Exchange::Money] The currency with the added value
|
176
178
|
# @raise [CurrencyMixError] If the configuration does not allow mixed operations, this method will raise an error if two different currencies are used in the operation
|
177
179
|
# @example Configuration disallows mixed operations
|
178
180
|
# Exchange.configuration.allow_mixed_operations = false
|
179
|
-
# Exchange::
|
181
|
+
# Exchange::Money.new(20,:nok) + Exchange::Money.new(20,:sek)
|
180
182
|
# #=> #<CurrencyMixError "You tried to mix currencies">
|
181
183
|
# @example Configuration allows mixed operations (default)
|
182
|
-
# Exchange::
|
183
|
-
# #=> #<Exchange::
|
184
|
+
# Exchange::Money.new(20,:nok) + Exchange::Money.new(20,:sek)
|
185
|
+
# #=> #<Exchange::Money @value=37.56 @currency=:nok>
|
184
186
|
# @since 0.1
|
185
187
|
# @version 0.7
|
186
188
|
#
|
187
189
|
base_operation '+'
|
188
190
|
|
189
191
|
# Subtract a value from the currency
|
190
|
-
# @param [Integer, Float, Exchange::
|
191
|
-
# @return [Exchange::
|
192
|
+
# @param [Integer, Float, Exchange::Money] other The value to be subtracted from the currency. If an Exchange::Money, it is converted to the instance's currency and then subtracted from the converted value.
|
193
|
+
# @return [Exchange::Money] The currency with the added value
|
192
194
|
# @raise [CurrencyMixError] If the configuration does not allow mixed operations, this method will raise an error if two different currencies are used in the operation
|
193
195
|
# @example Configuration disallows mixed operations
|
194
196
|
# Exchange.configuration.allow_mixed_operations = false
|
195
|
-
# Exchange::
|
197
|
+
# Exchange::Money.new(20,:nok) - Exchange::Money.new(20,:sek)
|
196
198
|
# #=> #<CurrencyMixError "You tried to mix currencies">
|
197
199
|
# @example Configuration allows mixed operations (default)
|
198
|
-
# Exchange::
|
199
|
-
# #=> #<Exchange::
|
200
|
+
# Exchange::Money.new(20,:nok) - Exchange::Money.new(20,:sek)
|
201
|
+
# #=> #<Exchange::Money @value=7.56 @currency=:nok>
|
200
202
|
# @since 0.1
|
201
203
|
# @version 0.7
|
202
204
|
#
|
203
205
|
base_operation '-'
|
204
206
|
|
205
207
|
# Multiply a value with the currency
|
206
|
-
# @param [Integer, Float, Exchange::
|
207
|
-
# @return [Exchange::
|
208
|
+
# @param [Integer, Float, Exchange::Money] other The value to be multiplied with the currency. If an Exchange::Money, it is converted to the instance's currency and multiplied with the converted value.
|
209
|
+
# @return [Exchange::Money] The currency with the multiplied value
|
208
210
|
# @raise [CurrencyMixError] If the configuration does not allow mixed operations, this method will raise an error if two different currencies are used in the operation
|
209
211
|
# @example Configuration disallows mixed operations
|
210
212
|
# Exchange.configuration.allow_mixed_operations = false
|
211
|
-
# Exchange::
|
213
|
+
# Exchange::Money.new(20,:nok) * Exchange::Money.new(20,:sek)
|
212
214
|
# #=> #<CurrencyMixError "You tried to mix currencies">
|
213
215
|
# @example Configuration allows mixed operations (default)
|
214
|
-
# Exchange::
|
215
|
-
# #=> #<Exchange::
|
216
|
+
# Exchange::Money.new(20,:nok) * Exchange::Money.new(20,:sek)
|
217
|
+
# #=> #<Exchange::Money @value=70.56 @currency=:nok>
|
216
218
|
# @since 0.1
|
217
219
|
# @version 0.7
|
218
220
|
#
|
219
221
|
base_operation '*'
|
220
222
|
|
221
223
|
# Divide the currency by a value
|
222
|
-
# @param [Integer, Float, Exchange::
|
223
|
-
# @return [Exchange::
|
224
|
+
# @param [Integer, Float, Exchange::Money] other The value to be divided by the currency. If an Exchange::Money, it is converted to the instance's currency and divided by the converted value.
|
225
|
+
# @return [Exchange::Money] The currency with the divided value
|
224
226
|
# @raise [CurrencyMixError] If the configuration does not allow mixed operations, this method will raise an error if two different currencies are used in the operation
|
225
227
|
# @example Configuration disallows mixed operations
|
226
228
|
# Exchange.configuration.allow_mixed_operations = false
|
227
|
-
# Exchange::
|
229
|
+
# Exchange::Money.new(20,:nok) / Exchange::Money.new(20,:sek)
|
228
230
|
# #=> #<CurrencyMixError "You tried to mix currencies">
|
229
231
|
# @example Configuration allows mixed operations (default)
|
230
|
-
# Exchange::
|
231
|
-
# #=> #<Exchange::
|
232
|
+
# Exchange::Money.new(20,:nok) / Exchange::Money.new(20,:sek)
|
233
|
+
# #=> #<Exchange::Money @value=1.56 @currency=:nok>
|
232
234
|
# @since 0.1
|
233
235
|
# @version 0.7
|
234
236
|
#
|
235
237
|
base_operation '/'
|
236
238
|
|
237
|
-
# Compare a currency with another currency or another value. If the other is not an instance of Exchange::
|
239
|
+
# Compare a currency with another currency or another value. If the other is not an instance of Exchange::Money, the value
|
238
240
|
# of the currency is compared
|
239
241
|
# @param [Whatever you want to throw at it] other The counterpart to compare
|
240
242
|
# @return [Boolean] true if the other is equal, false if not
|
241
243
|
# @example Compare two currencies
|
242
|
-
# Exchange::
|
244
|
+
# Exchange::Money.new(40, :usd) == Exchange::Money.new(34, :usd) #=> true
|
243
245
|
# @example Compare two different currencies, the other will get converted for comparison
|
244
|
-
# Exchange::
|
246
|
+
# Exchange::Money.new(40, :usd) == Exchange::Money.new(34, :eur) #=> true, will implicitly convert eur to usd at the actual rate
|
245
247
|
# @example Compare a currency with a number, the value of the currency will get compared
|
246
|
-
# Exchange::
|
248
|
+
# Exchange::Money.new(35, :usd) == 35 #=> true
|
247
249
|
# @since 0.1
|
248
250
|
# @version 0.6
|
249
251
|
#
|
@@ -251,13 +253,13 @@ module Exchange
|
|
251
253
|
if is_same_currency?(other)
|
252
254
|
other.round.value == self.round.value
|
253
255
|
elsif is_currency?(other)
|
254
|
-
other.convert_to(
|
256
|
+
other.convert_to(currency, :at => other.time).round.value == self.round.value
|
255
257
|
else
|
256
|
-
|
258
|
+
value == other
|
257
259
|
end
|
258
260
|
end
|
259
261
|
|
260
|
-
# Sortcompare a currency with another currency. If the other is not an instance of Exchange::
|
262
|
+
# Sortcompare a currency with another currency. If the other is not an instance of Exchange::Money, the value
|
261
263
|
# of the currency is compared. Different currencies will be converted to the comparing instances currency
|
262
264
|
# @param [Whatever you want to throw at it] other The counterpart to compare
|
263
265
|
# @return [Fixed] a number which can be used for sorting
|
@@ -265,19 +267,19 @@ module Exchange
|
|
265
267
|
# @version 0.6
|
266
268
|
# @todo which historic conversion should be used when two are present?
|
267
269
|
# @example Compare two currencies in terms of value
|
268
|
-
# Exchange::
|
270
|
+
# Exchange::Money.new(40, :usd) <=> Exchange::Money.new(28, :usd) #=> -1
|
269
271
|
# @example Compare two different currencies, the other will get converted for comparison
|
270
|
-
# Exchange::
|
272
|
+
# Exchange::Money.new(40, :usd) <=> Exchange::Money.new(28, :eur) #=> -1
|
271
273
|
# @example Sort multiple currencies in an array
|
272
274
|
# [1.usd, 1.eur, 1.chf].sort.map(&:currency) #=> [:usd, :chf, :eur]
|
273
275
|
#
|
274
276
|
def <=> other
|
275
277
|
if is_same_currency?(other)
|
276
|
-
|
278
|
+
value <=> other.value
|
277
279
|
elsif is_other_currency?(other)
|
278
|
-
|
280
|
+
value <=> other.convert_to(currency, :at => other.time).value
|
279
281
|
else
|
280
|
-
|
282
|
+
value <=> other
|
281
283
|
end
|
282
284
|
end
|
283
285
|
|
@@ -288,51 +290,51 @@ module Exchange
|
|
288
290
|
# @param [Symbol] format :currency (default) if you want a string with currency, :amount if you want just the amount.
|
289
291
|
# @return [String] The formatted string
|
290
292
|
# @example Convert a currency to a string
|
291
|
-
# Exchange::
|
293
|
+
# Exchange::Money.new(49.567, :usd).to_s #=> "USD 49.57"
|
292
294
|
# @example Convert a currency without minor to a string
|
293
|
-
# Exchange::
|
295
|
+
# Exchange::Money.new(45, :jpy).to_s #=> "JPY 45"
|
294
296
|
# @example Convert a currency with a three decimal minor to a string
|
295
|
-
# Exchange::
|
297
|
+
# Exchange::Money.new(34.34, :omr).to_s #=> "OMR 34.340"
|
296
298
|
# @example Convert a currency to a string without the currency
|
297
299
|
# Exchange::ISO4217.stringif(34.34, :omr).to_s(:iso) #=> "34.340"
|
298
300
|
#
|
299
301
|
def to_s format=:currency
|
300
302
|
[
|
301
|
-
format == :currency && ISO4217.stringify(
|
302
|
-
format == :amount && ISO4217.stringify(
|
303
|
+
format == :currency && ISO4217.stringify(value, currency),
|
304
|
+
format == :amount && ISO4217.stringify(value, currency, :amount_only => true)
|
303
305
|
].detect{|l| l.is_a?(String) }
|
304
306
|
end
|
305
307
|
|
306
308
|
private
|
307
309
|
|
308
|
-
# determine if another given object is an instance of Exchange::
|
310
|
+
# determine if another given object is an instance of Exchange::Money
|
309
311
|
# @param [Object] other The object to be tested against
|
310
|
-
# @return [Boolean] true if the other is an instance of Exchange::
|
312
|
+
# @return [Boolean] true if the other is an instance of Exchange::Money, false if not
|
311
313
|
# @since 0.6
|
312
314
|
# @version 0.6
|
313
315
|
#
|
314
316
|
def is_currency? other
|
315
|
-
other.is_a?(Exchange::
|
317
|
+
other.is_a?(Exchange::Money)
|
316
318
|
end
|
317
319
|
|
318
|
-
# determine if another given object is an instance of Exchange::
|
320
|
+
# determine if another given object is an instance of Exchange::Money and the same currency
|
319
321
|
# @param [Object] other The object to be tested against
|
320
|
-
# @return [Boolean] true if the other is an instance of Exchange::
|
322
|
+
# @return [Boolean] true if the other is an instance of Exchange::Money and has the same currency as self, false if not
|
321
323
|
# @since 0.6
|
322
324
|
# @version 0.6
|
323
325
|
#
|
324
326
|
def is_same_currency? other
|
325
|
-
is_currency?(other) && other.currency ==
|
327
|
+
is_currency?(other) && other.currency == currency
|
326
328
|
end
|
327
329
|
|
328
|
-
# determine if another given object is an instance of Exchange::
|
330
|
+
# determine if another given object is an instance of Exchange::Money and has another currency
|
329
331
|
# @param [Object] other The object to be tested against
|
330
|
-
# @return [Boolean] true if the other is an instance of Exchange::
|
332
|
+
# @return [Boolean] true if the other is an instance of Exchange::Money and has another currency as self, false if not
|
331
333
|
# @since 0.6
|
332
334
|
# @version 0.6
|
333
335
|
#
|
334
336
|
def is_other_currency? other
|
335
|
-
is_currency?(other) && other.currency !=
|
337
|
+
is_currency?(other) && other.currency != currency
|
336
338
|
end
|
337
339
|
|
338
340
|
# determine wether the chosen api supports converting the given currency
|
@@ -344,23 +346,23 @@ module Exchange
|
|
344
346
|
end
|
345
347
|
|
346
348
|
# Test if another currency is used in an operation, and if so, if the operation is allowed
|
347
|
-
# @param [Numeric, Exchange::
|
349
|
+
# @param [Numeric, Exchange::Money] other The counterpart in the operation
|
348
350
|
# @raise [CurrencyMixError] an error if mixing currencies is not allowed and currencies where mixed
|
349
351
|
# @since 0.6
|
350
352
|
# @version 0.6
|
351
353
|
#
|
352
354
|
def test_for_currency_mix_error other
|
353
|
-
raise CurrencyMixError.new("You\'re trying to mix up #{
|
355
|
+
raise CurrencyMixError.new("You\'re trying to mix up #{currency} with #{other.currency}. You denied mixing currencies in the configuration, allow it or convert the currencies before mixing") if !Exchange.configuration.allow_mixed_operations && other.kind_of?(Money) && other.currency != currency
|
354
356
|
end
|
355
357
|
|
356
358
|
# Helper method to raise a no rate error for a given currency if no rate is given
|
357
|
-
# @param [String]
|
359
|
+
# @param [String] other a possible currency
|
358
360
|
# @raise [NoRateError] an error indicating that the given string is a currency, but no rate is present
|
359
361
|
# @since 0.7.2
|
360
362
|
# @version 0.7.2
|
361
363
|
#
|
362
|
-
def
|
363
|
-
raise NoRateError.new("Cannot convert to #{
|
364
|
+
def raise_no_rate_error other
|
365
|
+
raise NoRateError.new("Cannot convert to #{other} because the defined api does not provide a rate")
|
364
366
|
end
|
365
367
|
|
366
368
|
end
|