money 2.3.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,8 @@
1
+ == Money 3.0.0
2
+ * Version Bump due to compatibility changes with ActiveRecord. See
3
+ http://github.com/FooBarWidget/money/issues#issue/4/comment/224880 for more
4
+ information.
5
+
1
6
  == Money 2.3.0
2
7
  * Currency is now represented by a Currency Object instead of a string.
3
8
 
data/README.rdoc CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  This library aids one in handling money and different currencies. Features:
4
4
 
5
- - Provides a Money class which encapsulates all information about an certain
5
+ - Provides a <tt>Money</tt> class which encapsulates all information about an certain
6
6
  amount of money, such as its value and its currency.
7
- - Provies a Currency class which encapsulates all information about
7
+ - Provies a <tt>Money::Currency</tt> class which encapsulates all information about
8
8
  a monerary unit.
9
9
  - Represents monetary values as integers, in cents. This avoids floating point
10
10
  rounding errors.
11
- - Represents currency as Currency instances providing an high level of flexibility.
11
+ - Represents currency as <tt>Money::Currency</tt> instances providing an high level of flexibility.
12
12
  - Provides APIs for exchanging money from one currency to another.
13
13
  - Has the ability to parse a money and currency strings
14
14
  into the corresponding Money/Currency object.
@@ -48,13 +48,13 @@ The development version (hosted on Github) can be installed with:
48
48
 
49
49
  === Currency
50
50
 
51
- Currencies are consistently represented as instances of Money::Currency.
52
- The most part of Money APIs allows you to supply either a String or a Currency.
51
+ Currencies are consistently represented as instances of <tt>Money::Currency</tt>.
52
+ The most part of <tt>Money</tt> APIs allows you to supply either a <tt>String</tt> or a <tt>Money::Currency</tt>.
53
53
 
54
54
  Money.new(1000, "USD") == Money.new(900, Currency.new("USD"))
55
55
  Money.new(1000, "EUR").currency == Currency.new("EUR")
56
56
 
57
- A Money::Currency instance holds all the information about the currency,
57
+ A <tt>Money::Currency</tt> instance holds all the information about the currency,
58
58
  including the currency symbol, name and much more.
59
59
 
60
60
  currency = Money.new(1000, "USD")
@@ -63,8 +63,8 @@ including the currency symbol, name and much more.
63
63
  currency.name
64
64
  # => "United States Dollar"
65
65
 
66
- To define a new Money::Currency simply add a new item to the Money::Currency::TABLE hash,
67
- where the key is the identifier for the Currency object and the value is a hash
66
+ To define a new <tt>Money::Currency</tt> simply add a new item to the <tt>Money::Currency::TABLE</tt> hash,
67
+ where the key is the identifier for the currency object and the value is a hash
68
68
  containing all the currency attributes.
69
69
 
70
70
  Money::Currency::TABLE[:usd] = {
@@ -85,13 +85,13 @@ The pre-defined set of attributes includes:
85
85
  * subunit: the name of the fractional monetary unit
86
86
  * subunit_to_unit: the proportion between the unit and the subunit
87
87
 
88
- All attributes are optional. Some attributes, such as :symbol, are used by the Money class
89
- to print out a representation of the object. Other attributes, such as :name or :priority,
88
+ All attributes are optional. Some attributes, such as <tt>:symbol</tt>, are used by the Money class
89
+ to print out a representation of the object. Other attributes, such as <tt>:name</tt> or <tt>:priority</tt>,
90
90
  exist to provide a basic API you can take advantage of to build your application.
91
91
 
92
92
  ==== priority
93
93
 
94
- The priority attribute is an arbitrary numerical value you can assign to the Currency
94
+ The priority attribute is an arbitrary numerical value you can assign to the <tt>Money::Currency</tt>
95
95
  and use in sorting/grouping operation.
96
96
 
97
97
  For instance, let's assume your Rails application needs to a currency selector
@@ -126,11 +126,11 @@ and all_currencies as follows:
126
126
 
127
127
  === Default Currency
128
128
 
129
- By default Money defaults to USD as its currency. This can be overwritten using
129
+ By default <tt>Money</tt> defaults to USD as its currency. This can be overwritten using
130
130
 
131
131
  Money.default_currency = Money::Currency.new("CAD")
132
132
 
133
- If you use Rails, then environment.rb is a very good place to put this.
133
+ If you use Rails, then <tt>environment.rb</tt> is a very good place to put this.
134
134
 
135
135
  === Currency Exchange
136
136
 
@@ -157,6 +157,13 @@ www.xe.com for the current rates or just returns <tt>rand(2)</tt>:
157
157
 
158
158
  Money.default_bank = ExchangeBankWhichScrapesXeDotCom.new
159
159
 
160
+ === Currency Exchange Implementations
161
+
162
+ The following is a list of Money.gem compatible currency exchange rate
163
+ implementations.
164
+
165
+ * eu_central_bank.gem: http://github.com/liangzan/eu_central_bank
166
+
160
167
  === Ruby on Rails
161
168
 
162
169
  Use the +compose_of+ helper to let Active Record deal with embedding the money
@@ -165,15 +172,40 @@ field.
165
172
 
166
173
  class ProductUnit < ActiveRecord::Base
167
174
  belongs_to :product
168
- composed_of :price, :class_name => "Money", :mapping => [%w(cents cents), %w(currency currency)]
175
+ composed_of :price, :class_name => "Money", :mapping => [%w(cents cents), %w(currency currency_as_string)]
169
176
 
170
- private
177
+ private
171
178
  validate :cents_not_zero
172
-
179
+
173
180
  def cents_not_zero
174
181
  errors.add("cents", "cannot be zero or less") unless cents > 0
175
182
  end
176
183
 
177
184
  validates_presence_of :sku, :currency
178
- validates_uniqueness_of :sku
185
+ validates_uniqueness_of :sku
186
+ end
187
+
188
+ Also, because the <tt>currency</tt> attribute is not a simple <tt>String</tt>
189
+ but a <tt>Money::Currency</tt> object, you need a small tweak to make it work.
190
+
191
+ Extend/hack the <tt>Money</tt> class with two additional methods:
192
+
193
+ # You can put this file in the config/initializers/ folder
194
+ class Money
195
+ def currency_as_string
196
+ currency.to_s
197
+ end
198
+
199
+ def currency_as_string=(value)
200
+ # WARNING: this method might cause data inconsistency.
201
+ # See http://github.com/FooBarWidget/money/issues/4#issue/4/comment/224930
202
+ # currency = Currency.wrap(value)
203
+ end
179
204
  end
205
+
206
+ The hack is not required for Money 2.2.x and previous versions.
207
+ In this case, simply use the following <tt>composed_of</tt> definition:
208
+
209
+ composed_of :price, :class_name => "Money", :mapping => [%w(cents cents), %w(currency currency)]
210
+
211
+ For further details read the full discussion at http://github.com/FooBarWidget/money/issues/4#comment_224880
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.0
1
+ 3.0.0
@@ -34,20 +34,20 @@ class String
34
34
  end
35
35
 
36
36
  private
37
-
37
+
38
38
  def calculate_cents(number)
39
39
  # remove anything that's not a number, potential delimiter, or minus sign
40
40
  num = number.gsub(/[^\d|\.|,|\'|\s|\-]/, '').strip
41
-
41
+
42
42
  # set a boolean flag for if the number is negative or not
43
43
  negative = num.split(//).first == "-"
44
-
44
+
45
45
  # if negative, remove the minus sign from the number
46
46
  num = num.gsub(/^-/, '') if negative
47
-
47
+
48
48
  # gather all separators within the result number
49
49
  used_separators = num.scan /[^\d]/
50
-
50
+
51
51
  # determine the number of unique separators within the number
52
52
  #
53
53
  # e.g.
@@ -58,8 +58,8 @@ class String
58
58
  case used_separators.uniq.length
59
59
  # no separator or delimiter; major (dollars) is the number, and minor (cents) is 0
60
60
  when 0 then major, minor = num, 0
61
-
62
- # two separators, so we know the last item in this array is the
61
+
62
+ # two separators, so we know the last item in this array is the
63
63
  # major/minor delimiter and the rest are separators
64
64
  when 2
65
65
  separator, delimiter = used_separators.uniq
@@ -75,10 +75,10 @@ class String
75
75
  # 1,000,000 - comma is a separator
76
76
  # 10000,00 - comma is a delimiter
77
77
  # 1000,000 - comma is a delimiter
78
-
78
+
79
79
  # assign first separator for reusability
80
80
  separator = used_separators.first
81
-
81
+
82
82
  # separator is used as a separator when there are multiple instances, always
83
83
  if num.scan(separator).length > 1 # multiple matches; treat as separator
84
84
  major, minor = num.gsub(separator, ''), 0
@@ -88,7 +88,7 @@ class String
88
88
  possible_major, possible_minor = num.split(separator)
89
89
  possible_major ||= "0"
90
90
  possible_minor ||= "00"
91
-
91
+
92
92
  # if the minor (cents) length isn't 3, assign major/minor from the possibles
93
93
  # e.g.
94
94
  # 1,00 => 1.00
@@ -99,8 +99,8 @@ class String
99
99
  else
100
100
  # minor length is three
101
101
  # let's try to figure out intent of the delimiter
102
-
103
- # the major length is greater than three, which means
102
+
103
+ # the major length is greater than three, which means
104
104
  # the comma or period is used as a delimiter
105
105
  # e.g.
106
106
  # 1000,000
@@ -121,7 +121,7 @@ class String
121
121
  else
122
122
  raise ArgumentError, "Invalid currency amount"
123
123
  end
124
-
124
+
125
125
  # build the string based on major/minor since separator/delimiters have been removed
126
126
  # avoiding floating point arithmetic here to ensure accuracy
127
127
  cents = (major.to_i * 100)
@@ -136,9 +136,9 @@ class String
136
136
  if minor.size >= 3 && minor[2..2].to_i >= 5
137
137
  cents += 1
138
138
  end
139
-
139
+
140
140
  # if negative, multiply by -1; otherwise, return positive cents
141
141
  negative ? cents * -1 : cents
142
142
  end
143
-
143
+
144
144
  end
@@ -265,7 +265,7 @@ class Money
265
265
  end
266
266
 
267
267
  # Wraps the object in a Currency unless it's a Currency.
268
- #
268
+ #
269
269
  # Currency.wrap(nil)
270
270
  # # => nil
271
271
  # Currency.wrap(Currency.new(:usd))
data/lib/money/money.rb CHANGED
@@ -15,11 +15,11 @@ class Money
15
15
  #
16
16
  # bank1 = MyBank.new
17
17
  # bank2 = MyOtherBank.new
18
- #
18
+ #
19
19
  # Money.default_bank = bank1
20
20
  # money1 = Money.new(10)
21
21
  # money1.bank # => bank1
22
- #
22
+ #
23
23
  # Money.default_bank = bank2
24
24
  # money2 = Money.new(10)
25
25
  # money2.bank # => bank2
@@ -33,17 +33,17 @@ class Money
33
33
  # Money.us_dollar(100).exchange_to("CAD") # => Money.ca_dollar(124)
34
34
  # Money.ca_dollar(100).exchange_to("USD") # => Money.us_dollar(80)
35
35
  attr_accessor :default_bank
36
-
36
+
37
37
  # The default currency, which is used when <tt>Money.new</tt> is called
38
38
  # without an explicit currency argument. The default value is Currency.new("USD").
39
39
  # The value must be a valid <tt>Money::Currency</tt> instance.
40
40
  attr_accessor :default_currency
41
41
  end
42
-
42
+
43
43
  self.default_bank = VariableExchangeBank.instance
44
44
  self.default_currency = Currency.new("USD")
45
-
46
-
45
+
46
+
47
47
  # Create a new money object with value 0.
48
48
  def self.empty(currency = default_currency)
49
49
  Money.new(0, currency)
@@ -58,22 +58,22 @@ class Money
58
58
  def self.us_dollar(cents)
59
59
  Money.new(cents, "USD")
60
60
  end
61
-
61
+
62
62
  # Creates a new Money object of the given value, using the Euro currency.
63
63
  def self.euro(cents)
64
64
  Money.new(cents, "EUR")
65
65
  end
66
-
66
+
67
67
  def self.add_rate(from_currency, to_currency, rate)
68
68
  Money.default_bank.add_rate(from_currency, to_currency, rate)
69
69
  end
70
-
71
-
72
- # Creates a new money object.
73
- # Money.new(100)
74
- #
75
- # Alternativly you can use the convinience methods like
76
- # Money.ca_dollar and Money.us_dollar
70
+
71
+
72
+ # Creates a new money object.
73
+ # Money.new(100)
74
+ #
75
+ # Alternatively you can use the convinience methods like
76
+ # Money.ca_dollar and Money.us_dollar
77
77
  def initialize(cents, currency = Money.default_currency, bank = Money.default_bank)
78
78
  @cents = cents.round
79
79
  if currency.is_a?(Hash)
@@ -101,7 +101,7 @@ class Money
101
101
  false
102
102
  end
103
103
  end
104
-
104
+
105
105
  # Compares this money object against another object. +other_money+ must respond
106
106
  # to #to_money.
107
107
  #
@@ -161,12 +161,17 @@ class Money
161
161
  Money.new(cents / val, currency)
162
162
  end
163
163
  end
164
-
164
+
165
165
  # Test if the money amount is zero
166
166
  def zero?
167
167
  cents == 0
168
168
  end
169
169
 
170
+ # Test if the money amount is non-zero. Returns this money object if it is
171
+ # non-zero, or nil otherwise, like <tt>Numeric#nonzero?</tt>.
172
+ def nonzero?
173
+ cents != 0 ? self : nil
174
+ end
170
175
 
171
176
  # Attempts to pick a symbol that's suitable for the given currency
172
177
  # looking up the Currency::TABLE hashtable.
@@ -201,58 +206,58 @@ class Money
201
206
  # Whether a zero amount of money should be formatted of "free" or as the
202
207
  # supplied string.
203
208
  #
204
- # Money.us_dollar(0).format(:display_free => true) => "free"
205
- # Money.us_dollar(0).format(:display_free => "gratis") => "gratis"
206
- # Money.us_dollar(0).format => "$0.00"
209
+ # Money.us_dollar(0).format(:display_free => true) => "free"
210
+ # Money.us_dollar(0).format(:display_free => "gratis") => "gratis"
211
+ # Money.us_dollar(0).format => "$0.00"
207
212
  #
208
213
  # === +:with_currency+
209
214
  #
210
215
  # Whether the currency name should be appended to the result string.
211
216
  #
212
- # Money.ca_dollar(100).format => "$1.00"
213
- # Money.ca_dollar(100).format(:with_currency => true) => "$1.00 CAD"
214
- # Money.us_dollar(85).format(:with_currency => true) => "$0.85 USD"
217
+ # Money.ca_dollar(100).format => "$1.00"
218
+ # Money.ca_dollar(100).format(:with_currency => true) => "$1.00 CAD"
219
+ # Money.us_dollar(85).format(:with_currency => true) => "$0.85 USD"
215
220
  #
216
221
  # === +:no_cents+
217
222
  #
218
223
  # Whether cents should be omitted.
219
224
  #
220
- # Money.ca_dollar(100).format(:no_cents => true) => "$1"
221
- # Money.ca_dollar(599).format(:no_cents => true) => "$5"
222
- #
223
- # Money.ca_dollar(570).format(:no_cents => true, :with_currency => true) => "$5 CAD"
224
- # Money.ca_dollar(39000).format(:no_cents => true) => "$390"
225
+ # Money.ca_dollar(100).format(:no_cents => true) => "$1"
226
+ # Money.ca_dollar(599).format(:no_cents => true) => "$5"
227
+ #
228
+ # Money.ca_dollar(570).format(:no_cents => true, :with_currency => true) => "$5 CAD"
229
+ # Money.ca_dollar(39000).format(:no_cents => true) => "$390"
225
230
  #
226
231
  # === +:symbol+
227
232
  #
228
233
  # Whether a money symbol should be prepended to the result string. The default is true.
229
234
  # This method attempts to pick a symbol that's suitable for the given currency.
230
235
  #
231
- # Money.new(100, "USD") => "$1.00"
232
- # Money.new(100, "GBP") => "£1.00"
233
- # Money.new(100, "EUR") => "€1.00"
234
- #
235
- # # Same thing.
236
- # Money.new(100, "USD").format(:symbol => true) => "$1.00"
237
- # Money.new(100, "GBP").format(:symbol => true) => "£1.00"
238
- # Money.new(100, "EUR").format(:symbol => true) => "€1.00"
236
+ # Money.new(100, "USD") => "$1.00"
237
+ # Money.new(100, "GBP") => "£1.00"
238
+ # Money.new(100, "EUR") => "€1.00"
239
+ #
240
+ # # Same thing.
241
+ # Money.new(100, "USD").format(:symbol => true) => "$1.00"
242
+ # Money.new(100, "GBP").format(:symbol => true) => "£1.00"
243
+ # Money.new(100, "EUR").format(:symbol => true) => "€1.00"
239
244
  #
240
245
  # You can specify a false expression or an empty string to disable prepending
241
246
  # a money symbol:
242
247
  #
243
- # Money.new(100, "USD").format(:symbol => false) => "1.00"
244
- # Money.new(100, "GBP").format(:symbol => nil) => "1.00"
245
- # Money.new(100, "EUR").format(:symbol => "") => "1.00"
248
+ # Money.new(100, "USD").format(:symbol => false) => "1.00"
249
+ # Money.new(100, "GBP").format(:symbol => nil) => "1.00"
250
+ # Money.new(100, "EUR").format(:symbol => "") => "1.00"
251
+ #
246
252
  #
247
- #
248
253
  # If the symbol for the given currency isn't known, then it will default
249
254
  # to "$" as symbol:
250
255
  #
251
- # Money.new(100, "AWG").format(:symbol => true) => "$1.00"
256
+ # Money.new(100, "AWG").format(:symbol => true) => "$1.00"
252
257
  #
253
258
  # You can specify a string as value to enforce using a particular symbol:
254
259
  #
255
- # Money.new(100, "AWG").format(:symbol => "ƒ") => "ƒ1.00"
260
+ # Money.new(100, "AWG").format(:symbol => "ƒ") => "ƒ1.00"
256
261
  #
257
262
  # === +:separator+
258
263
  #
@@ -260,42 +265,42 @@ class Money
260
265
  #
261
266
  # If a string is specified, it's value is used:
262
267
  #
263
- # Money.new(100, "USD").format(:separator => ",") => "$1,00"
268
+ # Money.new(100, "USD").format(:separator => ",") => "$1,00"
264
269
  #
265
270
  # If the separator for a given currency isn't known, then it will default to
266
271
  # "." as separator:
267
272
  #
268
- # Money.new(100, "FOO").format => "$1.00"
273
+ # Money.new(100, "FOO").format => "$1.00"
269
274
  #
270
275
  # === +:delimiter+
271
276
  #
272
277
  # Whether the currency should be delimited by the specified character or ','
273
278
  #
274
279
  # If false is specified, no delimiter is used:
275
- #
276
- # Money.new(100000, "USD").format(:delimiter => false) => "1000.00"
277
- # Money.new(100000, "USD").format(:delimiter => nil) => "1000.00"
278
- # Money.new(100000, "USD").format(:delimiter => "") => "1000.00"
280
+ #
281
+ # Money.new(100000, "USD").format(:delimiter => false) => "1000.00"
282
+ # Money.new(100000, "USD").format(:delimiter => nil) => "1000.00"
283
+ # Money.new(100000, "USD").format(:delimiter => "") => "1000.00"
279
284
  #
280
285
  # If a string is specified, it's value is used:
281
286
  #
282
- # Money.new(100000, "USD").format(:delimiter => ".") => "$1.000.00"
287
+ # Money.new(100000, "USD").format(:delimiter => ".") => "$1.000.00"
283
288
  #
284
289
  # If the delimiter for a given currency isn't known, then it will default to
285
290
  # "," as delimiter:
286
291
  #
287
- # Money.new(100000, "FOO").format => "$1,000.00"
292
+ # Money.new(100000, "FOO").format => "$1,000.00"
288
293
  #
289
294
  # === +:html+
290
295
  #
291
296
  # Whether the currency should be HTML-formatted. Only useful in combination with +:with_currency+.
292
297
  #
293
- # Money.ca_dollar(570).format(:html => true, :with_currency => true)
294
- # => "$5.70 <span class=\"currency\">CAD</span>"
298
+ # Money.ca_dollar(570).format(:html => true, :with_currency => true)
299
+ # # => "$5.70 <span class=\"currency\">CAD</span>"
295
300
  def format(*rules)
296
301
  # support for old format parameters
297
302
  rules = normalize_formatting_rules(rules)
298
-
303
+
299
304
  if cents == 0
300
305
  if rules[:display_free].respond_to?(:to_str)
301
306
  return rules[:display_free]
@@ -352,10 +357,11 @@ class Money
352
357
  end
353
358
  formatted
354
359
  end
355
-
360
+
356
361
  # Returns the amount of money as a string.
357
362
  #
358
- # Money.ca_dollar(100).to_s => "1.00"
363
+ # Money.ca_dollar(100).to_s => "1.00"
364
+ #
359
365
  def to_s
360
366
  sprintf("%.2f", cents / 100.00)
361
367
  end
@@ -365,12 +371,13 @@ class Money
365
371
  # need to represent currency or working with another system that requires
366
372
  # decimals.
367
373
  #
368
- # Money.us_dollar(100).to_f => 1.0
374
+ # Money.us_dollar(100).to_f => 1.0
375
+ #
369
376
  def to_f
370
377
  cents / 100.0
371
378
  end
372
379
 
373
- # Recieve the amount of this money object in another Currency.
380
+ # Receive the amount of this money object in another Currency.
374
381
  # <tt>other_currency</tt> can be either a <tt>String</tt>
375
382
  # or a <tt>Currency</tt> instance.
376
383
  #
@@ -382,31 +389,31 @@ class Money
382
389
  Money.new(@bank.exchange(self.cents, currency, other_currency), other_currency)
383
390
  end
384
391
 
385
- # Recieve a money object with the same amount as the current Money object
386
- # in american dollar
392
+ # Receive a money object with the same amount as the current Money object
393
+ # in american dollar
387
394
  def as_us_dollar
388
395
  exchange_to("USD")
389
396
  end
390
-
391
- # Recieve a money object with the same amount as the current Money object
392
- # in canadian dollar
397
+
398
+ # Receive a money object with the same amount as the current Money object
399
+ # in canadian dollar
393
400
  def as_ca_dollar
394
401
  exchange_to("CAD")
395
402
  end
396
-
397
- # Recieve a money object with the same amount as the current Money object
403
+
404
+ # Receive a money object with the same amount as the current Money object
398
405
  # in euro
399
406
  def as_euro
400
407
  exchange_to("EUR")
401
408
  end
402
-
409
+
403
410
  # Conversation to self
404
411
  def to_money
405
412
  self
406
413
  end
407
-
414
+
408
415
  private
409
-
416
+
410
417
  def normalize_formatting_rules(rules)
411
418
  if rules.size == 1
412
419
  rules = rules.pop
@@ -9,14 +9,15 @@ require 'money/errors'
9
9
  # One must manually specify them with +add_rate+, after which one can perform
10
10
  # exchanges with +exchange+. For example:
11
11
  #
12
- # bank = Money::VariableExchangeBank.new
13
- # bank.add_rate("USD", "CAD", 1.24515)
14
- # bank.add_rate("CAD", "USD", 0.803115)
15
- #
16
- # # Exchange 100 CAD to USD:
17
- # bank.exchange(100_00, "CAD", "USD") # => 124
18
- # # Exchange 100 USD to CAD:
19
- # bank.exchange(100_00, "USD", "CAD") # => 80
12
+ # bank = Money::VariableExchangeBank.new
13
+ # bank.add_rate("USD", "CAD", 1.24515)
14
+ # bank.add_rate("CAD", "USD", 0.803115)
15
+ #
16
+ # # Exchange 100 CAD to USD:
17
+ # bank.exchange(100_00, "CAD", "USD") # => 124
18
+ # # Exchange 100 USD to CAD:
19
+ # bank.exchange(100_00, "USD", "CAD") # => 80
20
+ #
20
21
  class Money
21
22
  class VariableExchangeBank
22
23
  # Returns the singleton instance of VariableExchangeBank.
@@ -25,27 +26,27 @@ class Money
25
26
  def self.instance
26
27
  @@singleton
27
28
  end
28
-
29
+
29
30
  def initialize
30
31
  @rates = {}
31
32
  @mutex = Mutex.new
32
33
  end
33
-
34
+
34
35
  # Registers a conversion rate. +from+ and +to+ are both currency names.
35
36
  def add_rate(from, to, rate)
36
37
  @mutex.synchronize do
37
38
  @rates["#{from}_TO_#{to}".upcase] = rate
38
39
  end
39
40
  end
40
-
41
+
41
42
  # Gets the rate for exchanging the currency named +from+ to the currency
42
43
  # named +to+. Returns nil if the rate is unknown.
43
44
  def get_rate(from, to)
44
45
  @mutex.synchronize do
45
- @rates["#{from}_TO_#{to}".upcase]
46
+ @rates["#{from}_TO_#{to}".upcase]
46
47
  end
47
48
  end
48
-
49
+
49
50
  # Given two currency names, checks whether they're both the same currency.
50
51
  #
51
52
  # bank = VariableExchangeBank.new
@@ -54,7 +55,7 @@ class Money
54
55
  def same_currency?(currency1, currency2)
55
56
  Currency.wrap(currency1) == Currency.wrap(currency2)
56
57
  end
57
-
58
+
58
59
  # Exchange the given amount of cents in +from_currency+ to +to_currency+.
59
60
  # Returns the amount of cents in +to_currency+ as an integer, rounded down.
60
61
  #
@@ -66,7 +67,7 @@ class Money
66
67
  end
67
68
  (cents * rate).floor
68
69
  end
69
-
70
+
70
71
  @@singleton = VariableExchangeBank.new
71
72
  end
72
73
  end
data/money.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{money}
8
- s.version = "2.3.0"
8
+ s.version = "3.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Tobias Luetke", "Hongli Lai", "Jeremy McNevin", "Shane Emmons"]
12
- s.date = %q{2010-04-16}
12
+ s.date = %q{2010-05-07}
13
13
  s.description = %q{Money and currency exchange support library.}
14
14
  s.email = %q{hongli@phusion.nl}
15
15
  s.extra_rdoc_files = [
@@ -55,7 +55,7 @@ describe Money::Currency do
55
55
  with_custom_definitions do
56
56
  Money::Currency::TABLE[:usd] = { :priority => 1, :iso_code => "USD", :name => "United States Dollar", :symbol => "$", :subunit => "Cent", :subunit_to_unit => "100" }
57
57
  Money::Currency::TABLE[:eur] = { :priority => 2, :iso_code => "EUR", :name => "Euro", :symbol => "€", :subunit => "Cent", :subunit_to_unit => "100" }
58
-
58
+
59
59
  expected = Money::Currency.new(:eur)
60
60
  Money::Currency.find(:eur).should == expected
61
61
  Money::Currency.find(:EUR).should == expected
@@ -63,12 +63,12 @@ describe Money::Currency do
63
63
  Money::Currency.find("EUR").should == expected
64
64
  end
65
65
  end
66
-
66
+
67
67
  specify "#self.find should return nil unless currency matching given id" do
68
68
  with_custom_definitions do
69
69
  Money::Currency::TABLE[:usd] = { :position => 1, :iso_code => "USD", :name => "United States Dollar", :symbol => "$", :subunit => "Cent", :subunit_to_unit => "100" }
70
70
  Money::Currency::TABLE[:eur] = { :position => 2, :iso_code => "EUR", :name => "Euro", :symbol => "€", :subunit => "Cent", :subunit_to_unit => "100" }
71
-
71
+
72
72
  expected = Money::Currency.new(:eur)
73
73
  Money::Currency.find(:eur).should == expected
74
74
  Money::Currency.find(:EUR).should == expected
@@ -5,14 +5,14 @@ describe Money::VariableExchangeBank do
5
5
  before :each do
6
6
  @bank = Money::VariableExchangeBank.new
7
7
  end
8
-
8
+
9
9
  it "returns the previously specified conversion rate" do
10
10
  @bank.add_rate("USD", "EUR", 0.788332676)
11
11
  @bank.add_rate("EUR", "YEN", 122.631477)
12
12
  @bank.get_rate("USD", "EUR").should == 0.788332676
13
13
  @bank.get_rate("EUR", "YEN").should == 122.631477
14
14
  end
15
-
15
+
16
16
  it "treats currency names case-insensitively" do
17
17
  @bank.add_rate("usd", "eur", 1)
18
18
  @bank.get_rate("USD", "EUR").should == 1
@@ -23,21 +23,21 @@ describe Money::VariableExchangeBank do
23
23
  it "returns nil if the conversion rate is unknown" do
24
24
  @bank.get_rate("American Pesos", "EUR").should be_nil
25
25
  end
26
-
26
+
27
27
  it "exchanges money from one currency to another according to the specified conversion rates" do
28
28
  @bank.add_rate("USD", "EUR", 0.5)
29
29
  @bank.add_rate("EUR", "YEN", 10)
30
30
  @bank.exchange(10_00, "USD", "EUR").should == 5_00
31
31
  @bank.exchange(500_00, "EUR", "YEN").should == 5000_00
32
32
  end
33
-
33
+
34
34
  it "rounds the exchanged result down" do
35
35
  @bank.add_rate("USD", "EUR", 0.788332676)
36
36
  @bank.add_rate("EUR", "YEN", 122.631477)
37
37
  @bank.exchange(10_00, "USD", "EUR").should == 788
38
38
  @bank.exchange(500_00, "EUR", "YEN").should == 6131573
39
39
  end
40
-
40
+
41
41
  it "raises Money::UnknownRate upon conversion if the conversion rate is unknown" do
42
42
  block = lambda { @bank.exchange(10, "USD", "EUR") }
43
43
  block.should raise_error(Money::UnknownRate)
data/test/money_spec.rb CHANGED
@@ -7,11 +7,11 @@ describe Money do
7
7
  it "is associated to the singleton instance of VariableExchangeBank by default" do
8
8
  Money.new(0).bank.object_id.should == Money::VariableExchangeBank.instance.object_id
9
9
  end
10
-
10
+
11
11
  specify "#cents returns the amount of cents passed to the constructor" do
12
12
  Money.new(200_00, "USD").cents.should == 200_00
13
13
  end
14
-
14
+
15
15
  it "rounds the given cents to an integer" do
16
16
  Money.new(1.00, "USD").cents.should == 1
17
17
  Money.new(1.01, "USD").cents.should == 1
@@ -21,7 +21,7 @@ describe Money do
21
21
  specify "#currency returns the currency passed to the constructor" do
22
22
  Money.new(200_00, "USD").currency.should == Money::Currency.new("USD")
23
23
  end
24
-
24
+
25
25
  specify "#zero? returns whether the amount is 0" do
26
26
  Money.new(0, "USD").should be_zero
27
27
  Money.new(0, "EUR").should be_zero
@@ -29,56 +29,71 @@ describe Money do
29
29
  Money.new(10, "YEN").should_not be_zero
30
30
  Money.new(-1, "EUR").should_not be_zero
31
31
  end
32
-
32
+
33
+ specify "#nonzero? returns whether the amount is not 0" do
34
+ Money.new(0, "USD").should_not be_nonzero
35
+ Money.new(0, "EUR").should_not be_nonzero
36
+ Money.new(1, "USD").should be_nonzero
37
+ Money.new(10, "YEN").should be_nonzero
38
+ Money.new(-1, "EUR").should be_nonzero
39
+ end
40
+
41
+ specify "#nonzero? has the same return-value semantics as Numeric#nonzero?" do
42
+ Money.new(0, "USD").nonzero?.should be_nil
43
+
44
+ money = Money.new(1, "USD")
45
+ money.nonzero?.should be_equal(money)
46
+ end
47
+
33
48
  specify "#exchange_to exchanges the amount via its exchange bank" do
34
49
  money = Money.new(100_00, "USD")
35
50
  money.bank.should_receive(:exchange).with(100_00, Money::Currency.new("USD"), Money::Currency.new("EUR")).and_return(200_00)
36
51
  money.exchange_to("EUR")
37
52
  end
38
-
53
+
39
54
  specify "#exchange_to exchanges the amount properly" do
40
55
  money = Money.new(100_00, "USD")
41
56
  money.bank.should_receive(:exchange).with(100_00, Money::Currency.new("USD"), Money::Currency.new("EUR")).and_return(200_00)
42
57
  money.exchange_to("EUR").should == Money.new(200_00, "EUR")
43
58
  end
44
-
59
+
45
60
  specify "#== returns true if and only if their amount and currency are equal" do
46
61
  Money.new(1_00, "USD").should == Money.new(1_00, "USD")
47
62
  Money.new(1_00, "USD").should_not == Money.new(1_00, "EUR")
48
63
  Money.new(1_00, "USD").should_not == Money.new(2_00, "USD")
49
64
  Money.new(1_00, "USD").should_not == Money.new(99_00, "EUR")
50
65
  end
51
-
66
+
52
67
  specify "#== can be used to compare with a String money value" do
53
68
  Money.new(1_00, "USD").should == "1.00"
54
69
  Money.new(1_00, "USD").should_not == "2.00"
55
70
  Money.new(1_00, "GBP").should_not == "1.00"
56
71
  end
57
-
72
+
58
73
  specify "#== can be used to compare with a Numeric money value" do
59
74
  Money.new(1_00, "USD").should == 1
60
75
  Money.new(1_57, "USD").should == 1.57
61
76
  Money.new(1_00, "USD").should_not == 2
62
77
  Money.new(1_00, "GBP").should_not == 1
63
78
  end
64
-
79
+
65
80
  specify "#== can be used to compare with an object that responds to #to_money" do
66
81
  klass = Class.new do
67
82
  def initialize(money)
68
83
  @money = money
69
84
  end
70
-
85
+
71
86
  def to_money
72
87
  @money
73
88
  end
74
89
  end
75
-
90
+
76
91
  Money.new(1_00, "USD").should == klass.new(Money.new(1_00, "USD"))
77
92
  Money.new(2_50, "USD").should == klass.new(Money.new(2_50, "USD"))
78
93
  Money.new(2_50, "USD").should_not == klass.new(Money.new(3_00, "USD"))
79
94
  Money.new(1_00, "GBP").should_not == klass.new(Money.new(1_00, "USD"))
80
95
  end
81
-
96
+
82
97
  specify "#== returns false if used to compare with an object that doesn't respond to #to_money" do
83
98
  Money.new(1_00, "USD").should_not == Object.new
84
99
  Money.new(1_00, "USD").should_not == Class
@@ -86,35 +101,35 @@ describe Money do
86
101
  Money.new(1_00, "USD").should_not == /foo/
87
102
  Money.new(1_00, "USD").should_not == nil
88
103
  end
89
-
104
+
90
105
  specify "#<=> can be used to compare with a String money value" do
91
106
  (Money.new(1_00) <=> "1.00").should == 0
92
107
  (Money.new(1_00) <=> ".99").should > 0
93
108
  (Money.new(1_00) <=> "2.00").should < 0
94
109
  end
95
-
110
+
96
111
  specify "#<=> can be used to compare with a Numeric money value" do
97
112
  (Money.new(1_00) <=> 1).should == 0
98
113
  (Money.new(1_00) <=> 0.99).should > 0
99
114
  (Money.new(1_00) <=> 2.00).should < 0
100
115
  end
101
-
116
+
102
117
  specify "#<=> can be used to compare with an object that responds to #to_money" do
103
118
  klass = Class.new do
104
119
  def initialize(money)
105
120
  @money = money
106
121
  end
107
-
122
+
108
123
  def to_money
109
124
  @money
110
125
  end
111
126
  end
112
-
127
+
113
128
  (Money.new(1_00) <=> klass.new(Money.new(1_00))).should == 0
114
129
  (Money.new(1_00) <=> klass.new(Money.new(99))).should > 0
115
130
  (Money.new(1_00) <=> klass.new(Money.new(2_00))).should < 0
116
131
  end
117
-
132
+
118
133
  specify "#<=> raises ArgumentError when used to compare with an object that doesn't respond to #to_money" do
119
134
  expected_message = /comparison .+ failed/
120
135
  lambda{ Money.new(1_00) <=> Object.new }.should raise_error(ArgumentError, expected_message)
@@ -122,39 +137,39 @@ describe Money do
122
137
  lambda{ Money.new(1_00) <=> Kernel }.should raise_error(ArgumentError, expected_message)
123
138
  lambda{ Money.new(1_00) <=> /foo/ }.should raise_error(ArgumentError, expected_message)
124
139
  end
125
-
140
+
126
141
  specify "#* multiplies the money's amount by the multiplier while retaining the currency" do
127
142
  (Money.new(1_00, "USD") * 10).should == Money.new(10_00, "USD")
128
143
  end
129
-
144
+
130
145
  specify "#/ divides the money's amount by the divisor while retaining the currency" do
131
146
  (Money.new(10_00, "USD") / 10).should == Money.new(1_00, "USD")
132
147
  end
133
-
148
+
134
149
  specify "Money.empty creates a new Money object of 0 cents" do
135
150
  Money.empty.should == Money.new(0)
136
151
  end
137
-
152
+
138
153
  specify "Money.ca_dollar creates a new Money object of the given value in CAD" do
139
154
  Money.ca_dollar(50).should == Money.new(50, "CAD")
140
155
  end
141
-
156
+
142
157
  specify "Money.ca_dollar creates a new Money object of the given value in USD" do
143
158
  Money.us_dollar(50).should == Money.new(50, "USD")
144
159
  end
145
-
160
+
146
161
  specify "Money.ca_dollar creates a new Money object of the given value in EUR" do
147
162
  Money.euro(50).should == Money.new(50, "EUR")
148
163
  end
149
-
164
+
150
165
  specify "Money.new accepts { :currency => 'foo' } as the value for the 'currency' argument" do
151
166
  money = Money.new(20, :currency => "EUR")
152
167
  money.currency.should == Money::Currency.new("EUR")
153
-
168
+
154
169
  money = Money.new(20, :currency => nil)
155
170
  money.currency.should == Money.default_currency
156
171
  end
157
-
172
+
158
173
  specify "Money.add_rate works" do
159
174
  Money.add_rate("EUR", "USD", 10)
160
175
  Money.new(10_00, "EUR").exchange_to("USD").should == Money.new(100_00, "USD")
@@ -167,7 +182,7 @@ describe Money do
167
182
  specify "Money.to_f works" do
168
183
  Money.new(10_00).to_f.should == 10.0
169
184
  end
170
-
185
+
171
186
  describe "#format" do
172
187
  it "returns the monetary value as a string" do
173
188
  Money.ca_dollar(100).format.should == "$1.00"
@@ -180,50 +195,50 @@ describe Money do
180
195
 
181
196
  # Pounds
182
197
  one_thousand["GBP"].should == "£1,000.00"
183
-
198
+
184
199
  # Dollars
185
200
  one_thousand["USD"].should == "$1,000.00"
186
201
  one_thousand["CAD"].should == "$1,000.00"
187
202
  one_thousand["AUD"].should == "$1,000.00"
188
203
  one_thousand["NZD"].should == "$1,000.00"
189
204
  one_thousand["ZWD"].should == "$1,000.00"
190
-
205
+
191
206
  # Yen
192
- one_thousand["JPY"].should == "¥1,000.00"
193
- one_thousand["CNY"].should == "¥1,000.00"
194
-
207
+ one_thousand["JPY"].should == "¥1,000.00"
208
+ one_thousand["CNY"].should == "¥1,000.00"
209
+
195
210
  # Euro
196
211
  one_thousand["EUR"].should == "€1,000.00"
197
-
212
+
198
213
  # Rupees
199
214
  one_thousand["INR"].should == "₨1,000.00"
200
215
  one_thousand["NPR"].should == "₨1,000.00"
201
216
  one_thousand["SCR"].should == "₨1,000.00"
202
217
  one_thousand["LKR"].should == "₨1,000.00"
203
-
218
+
204
219
  # Brazilian Real
205
220
  one_thousand["BRL"].should == "R$ 1.000,00"
206
-
221
+
207
222
  # Other
208
223
  one_thousand["SEK"].should == "kr1,000.00"
209
224
  one_thousand["GHC"].should == "₵1,000.00"
210
225
  end
211
-
226
+
212
227
  describe "if the monetary value is 0" do
213
228
  before :each do
214
229
  @money = Money.us_dollar(0)
215
230
  end
216
-
231
+
217
232
  it "returns 'free' when :display_free is true" do
218
233
  @money.format(:display_free => true).should == 'free'
219
234
  end
220
-
235
+
221
236
  it "returns '$0.00' when :display_free is false or not given" do
222
237
  @money.format.should == '$0.00'
223
238
  @money.format(:display_free => false).should == '$0.00'
224
239
  @money.format(:display_free => nil).should == '$0.00'
225
240
  end
226
-
241
+
227
242
  it "returns the value specified by :display_free if it's a string-like object" do
228
243
  @money.format(:display_free => 'gratis').should == 'gratis'
229
244
  end
@@ -255,7 +270,7 @@ describe Money do
255
270
  end
256
271
  end
257
272
  end
258
-
273
+
259
274
  specify "#separator works as documented" do
260
275
  begin
261
276
  old = Money::SEPARATORS.dup
@@ -277,12 +292,12 @@ describe Money do
277
292
  Money.us_dollar(85).format(:with_currency => true).should == "$0.85 USD"
278
293
  Money.us_dollar(85).format(:with_currency).should == "$0.85 USD"
279
294
  end
280
-
295
+
281
296
  specify "#format(:with_currency) works as documented" do
282
297
  Money.ca_dollar(100).format(:with_currency).should == "$1.00 CAD"
283
298
  Money.us_dollar(85).format(:with_currency).should == "$0.85 USD"
284
299
  end
285
-
300
+
286
301
  specify "#format(:no_cents => true) works as documented" do
287
302
  Money.ca_dollar(100).format(:no_cents => true).should == "$1"
288
303
  Money.ca_dollar(599).format(:no_cents => true).should == "$5"
@@ -296,11 +311,11 @@ describe Money do
296
311
  Money.ca_dollar(570).format(:no_cents, :with_currency).should == "$5 CAD"
297
312
  Money.ca_dollar(39000).format(:no_cents).should == "$390"
298
313
  end
299
-
314
+
300
315
  specify "#format(:symbol => a symbol string) uses the given value as the money symbol" do
301
316
  Money.new(100, "GBP").format(:symbol => "£").should == "£1.00"
302
317
  end
303
-
318
+
304
319
  specify "#format(:symbol => true) returns symbol based on the given currency code" do
305
320
  one = Proc.new do |currency|
306
321
  Money.new(100, currency).format(:symbol => true)
@@ -308,61 +323,61 @@ describe Money do
308
323
 
309
324
  # Pounds
310
325
  one["GBP"].should == "£1.00"
311
-
326
+
312
327
  # Dollars
313
328
  one["USD"].should == "$1.00"
314
329
  one["CAD"].should == "$1.00"
315
330
  one["AUD"].should == "$1.00"
316
331
  one["NZD"].should == "$1.00"
317
332
  one["ZWD"].should == "$1.00"
318
-
333
+
319
334
  # Yen
320
- one["JPY"].should == "¥1.00"
321
- one["CNY"].should == "¥1.00"
322
-
335
+ one["JPY"].should == "¥1.00"
336
+ one["CNY"].should == "¥1.00"
337
+
323
338
  # Euro
324
339
  one["EUR"].should == "€1.00"
325
-
340
+
326
341
  # Rupees
327
342
  one["INR"].should == "₨1.00"
328
343
  one["NPR"].should == "₨1.00"
329
344
  one["SCR"].should == "₨1.00"
330
345
  one["LKR"].should == "₨1.00"
331
-
346
+
332
347
  # Brazilian Real
333
348
  one["BRL"].should == "R$ 1,00"
334
-
349
+
335
350
  # Other
336
351
  one["SEK"].should == "kr1.00"
337
352
  one["GHC"].should == "₵1.00"
338
353
  end
339
-
354
+
340
355
  specify "#format(:symbol => true) returns $ when currency code is not recognized" do
341
356
  currency = Money::Currency.new("EUR")
342
357
  currency.should_receive(:symbol).and_return(nil)
343
358
  Money.new(100, currency).format(:symbol => true).should == "$1.00"
344
359
  end
345
-
360
+
346
361
  specify "#format(:symbol => some non-Boolean value that evaluates to true) returs symbol based on the given currency code" do
347
362
  Money.new(100, "GBP").format(:symbol => true).should == "£1.00"
348
363
  Money.new(100, "EUR").format(:symbol => true).should == "€1.00"
349
364
  Money.new(100, "SEK").format(:symbol => true).should == "kr1.00"
350
365
  end
351
-
366
+
352
367
  specify "#format with :symbol == "", nil or false returns the amount without a symbol" do
353
368
  money = Money.new(100, "GBP")
354
369
  money.format(:symbol => "").should == "1.00"
355
370
  money.format(:symbol => nil).should == "1.00"
356
371
  money.format(:symbol => false).should == "1.00"
357
372
  end
358
-
373
+
359
374
  specify "#format without :symbol assumes that :symbol is set to true" do
360
375
  money = Money.new(100)
361
376
  money.format.should == "$1.00"
362
-
377
+
363
378
  money = Money.new(100, "GBP")
364
379
  money.format.should == "£1.00"
365
-
380
+
366
381
  money = Money.new(100, "EUR")
367
382
  money.format.should == "€1.00"
368
383
  end
@@ -388,12 +403,12 @@ describe Money do
388
403
  specify "#format will default delimiter to ',' if currency isn't recognized" do
389
404
  Money.new(100000, "ZWD").format.should == "$1,000.00"
390
405
  end
391
-
406
+
392
407
  specify "#format(:html => true) works as documented" do
393
408
  string = Money.ca_dollar(570).format(:html => true, :with_currency => true)
394
409
  string.should == "$5.70 <span class=\"currency\">CAD</span>"
395
410
  end
396
-
411
+
397
412
  it "should insert commas into the result if the amount is sufficiently large" do
398
413
  Money.us_dollar(1_000_000_000_12).format.should == "$1,000,000,000.12"
399
414
  Money.us_dollar(1_000_000_000_12).format(:no_cents => true).should == "$1,000,000,000"
@@ -424,11 +439,11 @@ describe "Actions involving two Money objects" do
424
439
  (Money.new(1_00, "USD") <=> Money.new(99, "USD")).should > 0
425
440
  (Money.new(1_00, "USD") <=> Money.new(2_00, "USD")).should < 0
426
441
  end
427
-
442
+
428
443
  specify "#+ adds the other object's amount to the current object's amount while retaining the currency" do
429
444
  (Money.new(10_00, "USD") + Money.new(90, "USD")).should == Money.new(10_90, "USD")
430
445
  end
431
-
446
+
432
447
  specify "#- substracts the other object's amount from the current object's amount while retaining the currency" do
433
448
  (Money.new(10_00, "USD") - Money.new(90, "USD")).should == Money.new(9_10, "USD")
434
449
  end
@@ -437,28 +452,28 @@ describe "Actions involving two Money objects" do
437
452
  (Money.new(10_00, "USD") / Money.new(100_00, "USD")).should == 0.1
438
453
  end
439
454
  end
440
-
455
+
441
456
  describe "if the other Money object has a different currency" do
442
457
  specify "#<=> compares the two objects' amount after converting the other object's amount to its own currency" do
443
458
  target = Money.new(200_00, "EUR")
444
459
  target.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(300_00, "USD"))
445
460
  (Money.new(100_00, "USD") <=> target).should < 0
446
-
461
+
447
462
  target = Money.new(200_00, "EUR")
448
463
  target.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(100_00, "USD"))
449
464
  (Money.new(100_00, "USD") <=> target).should == 0
450
-
465
+
451
466
  target = Money.new(200_00, "EUR")
452
467
  target.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(99_00, "USD"))
453
468
  (Money.new(100_00, "USD") <=> target).should > 0
454
469
  end
455
-
470
+
456
471
  specify "#+ adds the other object's amount, converted to this object's currency, to this object's amount while retaining its currency" do
457
472
  other = Money.new(90, "EUR")
458
473
  other.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(9_00, "USD"))
459
474
  (Money.new(10_00, "USD") + other).should == Money.new(19_00, "USD")
460
475
  end
461
-
476
+
462
477
  specify "#- substracts the other object's amount, converted to this object's currency, from this object's amount while retaining its currency" do
463
478
  other = Money.new(90, "EUR")
464
479
  other.should_receive(:exchange_to).with(Money::Currency.new("USD")).and_return(Money.new(9_00, "USD"))
metadata CHANGED
@@ -3,10 +3,10 @@ name: money
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
- - 2
7
6
  - 3
8
7
  - 0
9
- version: 2.3.0
8
+ - 0
9
+ version: 3.0.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Tobias Luetke
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2010-04-16 00:00:00 -04:00
20
+ date: 2010-05-07 00:00:00 -04:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency