money 4.0.1 → 4.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,82 +1,82 @@
1
- # Open +Numeric+ to add new method.
2
- class Numeric
3
-
4
- # Converts this numeric into a +Money+ object in the given +currency+.
5
- #
6
- # @param [Currency, String, Symbol] currency
7
- # The currency to set the resulting +Money+ object to.
8
- #
9
- # @return [Money]
10
- #
11
- # @example
12
- # 100.to_money #=> #<Money @cents=10000>
13
- # 100.37.to_money #=> #<Money @cents=10037>
14
- # BigDecimal.new('100').to_money #=> #<Money @cents=10000>
15
- #
16
- # @see Money.from_numeric
17
- #
18
- def to_money(currency = nil)
19
- Money.from_numeric(self, currency || Money.default_currency)
20
- end
21
-
22
- end
23
-
24
- # Open +String+ to add new methods.
25
- class String
26
-
27
- # Parses the current string and converts it to a +Money+ object.
28
- # Excess characters will be discarded.
29
- #
30
- # @param [Currency, String, Symbol] currency
31
- # The currency to set the resulting +Money+ object to.
32
- #
33
- # @return [Money]
34
- #
35
- # @example
36
- # '100'.to_money #=> #<Money @cents=10000>
37
- # '100.37'.to_money #=> #<Money @cents=10037>
38
- # '100 USD'.to_money #=> #<Money @cents=10000, @currency=#<Money::Currency id: usd>>
39
- # 'USD 100'.to_money #=> #<Money @cents=10000, @currency=#<Money::Currency id: usd>>
40
- # '$100 USD'.to_money #=> #<Money @cents=10000, @currency=#<Money::Currency id: usd>>
41
- # 'hello 2000 world'.to_money #=> #<Money @cents=200000 @currency=#<Money::Currency id: usd>>
42
- #
43
- # @see Money.from_string
44
- #
45
- def to_money(currency = nil)
46
- Money.parse(self, currency)
47
- end
48
-
49
- # Converts the current string into a +Currency+ object.
50
- #
51
- # @return [Money::Currency]
52
- #
53
- # @raise [Money::Currency::UnknownCurrency]
54
- # If this String reference an unknown currency.
55
- #
56
- # @example
57
- # "USD".to_currency #=> #<Money::Currency id: usd>
58
- #
59
- def to_currency
60
- Money::Currency.new(self)
61
- end
62
-
63
- end
64
-
65
- # Open +Symbol+ to add new methods.
66
- class Symbol
67
-
68
- # Converts the current symbol into a +Currency+ object.
69
- #
70
- # @return [Money::Currency]
71
- #
72
- # @raise [Money::Currency::UnknownCurrency]
73
- # If this String reference an unknown currency.
74
- #
75
- # @example
76
- # :ars.to_currency #=> #<Money::Currency id: ars>
77
- #
78
- def to_currency
79
- Money::Currency.new(self)
80
- end
81
-
82
- end
1
+ # Open +Numeric+ to add new method.
2
+ class Numeric
3
+
4
+ # Converts this numeric into a +Money+ object in the given +currency+.
5
+ #
6
+ # @param [Currency, String, Symbol] currency
7
+ # The currency to set the resulting +Money+ object to.
8
+ #
9
+ # @return [Money]
10
+ #
11
+ # @example
12
+ # 100.to_money #=> #<Money @cents=10000>
13
+ # 100.37.to_money #=> #<Money @cents=10037>
14
+ # BigDecimal.new('100').to_money #=> #<Money @cents=10000>
15
+ #
16
+ # @see Money.from_numeric
17
+ #
18
+ def to_money(currency = nil)
19
+ Money.from_numeric(self, currency || Money.default_currency)
20
+ end
21
+
22
+ end
23
+
24
+ # Open +String+ to add new methods.
25
+ class String
26
+
27
+ # Parses the current string and converts it to a +Money+ object.
28
+ # Excess characters will be discarded.
29
+ #
30
+ # @param [Currency, String, Symbol] currency
31
+ # The currency to set the resulting +Money+ object to.
32
+ #
33
+ # @return [Money]
34
+ #
35
+ # @example
36
+ # '100'.to_money #=> #<Money @cents=10000>
37
+ # '100.37'.to_money #=> #<Money @cents=10037>
38
+ # '100 USD'.to_money #=> #<Money @cents=10000, @currency=#<Money::Currency id: usd>>
39
+ # 'USD 100'.to_money #=> #<Money @cents=10000, @currency=#<Money::Currency id: usd>>
40
+ # '$100 USD'.to_money #=> #<Money @cents=10000, @currency=#<Money::Currency id: usd>>
41
+ # 'hello 2000 world'.to_money #=> #<Money @cents=200000 @currency=#<Money::Currency id: usd>>
42
+ #
43
+ # @see Money.from_string
44
+ #
45
+ def to_money(currency = nil)
46
+ Money.parse(self, currency)
47
+ end
48
+
49
+ # Converts the current string into a +Currency+ object.
50
+ #
51
+ # @return [Money::Currency]
52
+ #
53
+ # @raise [Money::Currency::UnknownCurrency]
54
+ # If this String reference an unknown currency.
55
+ #
56
+ # @example
57
+ # "USD".to_currency #=> #<Money::Currency id: usd>
58
+ #
59
+ def to_currency
60
+ Money::Currency.new(self)
61
+ end
62
+
63
+ end
64
+
65
+ # Open +Symbol+ to add new methods.
66
+ class Symbol
67
+
68
+ # Converts the current symbol into a +Currency+ object.
69
+ #
70
+ # @return [Money::Currency]
71
+ #
72
+ # @raise [Money::Currency::UnknownCurrency]
73
+ # If this String reference an unknown currency.
74
+ #
75
+ # @example
76
+ # :ars.to_currency #=> #<Money::Currency id: ars>
77
+ #
78
+ def to_currency
79
+ Money::Currency.new(self)
80
+ end
81
+
82
+ end
@@ -1,263 +1,280 @@
1
- # encoding: utf-8
2
-
3
- require "json"
4
-
5
- class Money
6
-
7
- # Represents a specific currency unit.
8
- class Currency
9
- include Comparable
10
- extend CurrencyLoader
11
-
12
- # Thrown when an unknown currency is requested.
13
- class UnknownCurrency < StandardError; end
14
-
15
- # List of known currencies.
16
- #
17
- # == monetary unit
18
- # The standard unit of value of a currency, as the dollar in the United States or the peso in Mexico.
19
- # http://www.answers.com/topic/monetary-unit
20
- # == fractional monetary unit, subunit
21
- # A monetary unit that is valued at a fraction (usually one hundredth) of the basic monetary unit
22
- # http://www.answers.com/topic/fractional-monetary-unit-subunit
23
- #
24
- # See http://en.wikipedia.org/wiki/List_of_circulating_currencies and
25
- # http://search.cpan.org/~tnguyen/Locale-Currency-Format-1.28/Format.pm
26
-
27
- TABLE = load_currencies
28
-
29
-
30
- # The symbol used to identify the currency, usually the lowercase
31
- # +iso_code+ attribute.
32
- #
33
- # @return [Symbol]
34
- attr_reader :id
35
-
36
- # A numerical value you can use to sort/group the currency list.
37
- #
38
- # @return [Integer]
39
- attr_reader :priority
40
-
41
- # The international 3-letter code as defined by the ISO 4217 standard.
42
- #
43
- # @return [String]
44
- attr_reader :iso_code
45
- #
46
- # The international 3-numeric code as defined by the ISO 4217 standard.
47
- #
48
- # @return [String]
49
- attr_reader :iso_numeric
50
-
51
- # The currency name.
52
- #
53
- # @return [String]
54
- attr_reader :name
55
-
56
- # The currency symbol (UTF-8 encoded).
57
- #
58
- # @return [String]
59
- attr_reader :symbol
60
-
61
- # The html entity for the currency symbol
62
- #
63
- # @return [String]
64
- attr_reader :html_entity
65
-
66
- # The name of the fractional monetary unit.
67
- #
68
- # @return [String]
69
- attr_reader :subunit
70
-
71
- # The proportion between the unit and the subunit
72
- #
73
- # @return [Integer]
74
- attr_reader :subunit_to_unit
75
-
76
- # The decimal mark, or character used to separate the whole unit from the subunit.
77
- #
78
- # @return [String]
79
- attr_reader :decimal_mark
80
- alias :separator :decimal_mark
81
-
82
- # The character used to separate thousands grouping of the whole unit.
83
- #
84
- # @return [String]
85
- attr_reader :thousands_separator
86
- alias :delimiter :thousands_separator
87
-
88
- # Should the currency symbol precede the amount, or should it come after?
89
- #
90
- # @return [boolean]
91
- attr_reader :symbol_first
92
-
93
- def symbol_first?
94
- !!@symbol_first
95
- end
96
-
97
- # The number of decimal places needed.
98
- #
99
- # @return [Integer]
100
- def decimal_places
101
- if subunit_to_unit == 1
102
- 0
103
- elsif subunit_to_unit % 10 == 0
104
- Math.log10(subunit_to_unit).to_s.to_i
105
- else
106
- Math.log10(subunit_to_unit).to_s.to_i+1
107
- end
108
- end
109
-
110
- # Create a new +Currency+ object.
111
- #
112
- # @param [String, Symbol, #to_s] id Used to look into +TABLE+ and retrieve
113
- # the applicable attributes.
114
- #
115
- # @return [Money::Currency]
116
- #
117
- # @example
118
- # Money::Currency.new(:usd) #=> #<Money::Currency id: usd ...>
119
- def initialize(id)
120
- @id = id.to_s.downcase.to_sym
121
- data = TABLE[@id] || raise(UnknownCurrency, "Unknown currency `#{id}'")
122
- data.each_pair do |key, value|
123
- instance_variable_set(:"@#{key}", value)
124
- end
125
- end
126
-
127
- # Compares +self+ with +other_currency+ against the value of +priority+
128
- # attribute.
129
- #
130
- # @param [Money::Currency] other_currency The currency to compare to.
131
- #
132
- # @return [-1,0,1] -1 if less than, 0 is equal to, 1 if greater than
133
- #
134
- # @example
135
- # c1 = Money::Currency.new(:usd)
136
- # c2 = Money::Currency.new(:jpy)
137
- # c1 <=> c2 #=> 1
138
- # c2 <=> c1 #=> -1
139
- # c1 <=> c1 #=> 0
140
- def <=>(other_currency)
141
- self.priority <=> other_currency.priority
142
- end
143
-
144
- # Compares +self+ with +other_currency+ and returns +true+ if the are the
145
- # same or if their +id+ attributes match.
146
- #
147
- # @param [Money::Currency] other_currency The currency to compare to.
148
- #
149
- # @return [Boolean]
150
- #
151
- # @example
152
- # c1 = Money::Currency.new(:usd)
153
- # c2 = Money::Currency.new(:jpy)
154
- # c1 == c1 #=> true
155
- # c1 == c2 #=> false
156
- def ==(other_currency)
157
- self.equal?(other_currency) ||
158
- self.id == other_currency.id
159
- end
160
-
161
- # Compares +self+ with +other_currency+ and returns +true+ if the are the
162
- # same or if their +id+ attributes match.
163
- #
164
- # @param [Money::Currency] other_currency The currency to compare to.
165
- #
166
- # @return [Boolean]
167
- #
168
- # @example
169
- # c1 = Money::Currency.new(:usd)
170
- # c2 = Money::Currency.new(:jpy)
171
- # c1.eql? c1 #=> true
172
- # c1.eql? c2 #=> false
173
- def eql?(other_currency)
174
- self == other_currency
175
- end
176
-
177
- # Returns a Fixnum hash value based on the +id+ attribute in order to use
178
- # functions like & (intersection), group_by, etc.
179
- #
180
- # @return [Fixnum]
181
- #
182
- # @example
183
- # Money::Currency.new(:usd).hash #=> 428936
184
- def hash
185
- id.hash
186
- end
187
-
188
- # Returns a string representation corresponding to the upcase +id+
189
- # attribute.
190
- #
191
- # -–
192
- # DEV: id.to_s.upcase corresponds to iso_code but don't use ISO_CODE for consistency.
193
- #
194
- # @return [String]
195
- #
196
- # @example
197
- # Money::Currency.new(:usd).to_s #=> "USD"
198
- # Money::Currency.new(:eur).to_s #=> "EUR"
199
- def to_s
200
- id.to_s.upcase
201
- end
202
-
203
- # Conversation to +self+.
204
- #
205
- # @return [self]
206
- def to_currency
207
- self
208
- end
209
-
210
- # Returns a human readable representation.
211
- #
212
- # @return [String]
213
- #
214
- # @example
215
- # Money::Currency.new(:usd) #=> #<Currency id: usd ...>
216
- def inspect
217
- "#<#{self.class.name} id: #{id}, priority: #{priority}, symbol_first: #{symbol_first}, thousands_separator: #{thousands_separator}, html_entity: #{html_entity}, decimal_mark: #{decimal_mark}, name: #{name}, symbol: #{symbol}, subunit_to_unit: #{subunit_to_unit}, iso_code: #{iso_code}, iso_numeric: #{iso_numeric}, subunit: #{subunit}>"
218
- end
219
-
220
- # Class Methods
221
- class << self
222
-
223
- # Lookup a currency with given +id+ an returns a +Currency+ instance on
224
- # success, +nil+ otherwise.
225
- #
226
- # @param [String, Symbol, #to_s] id Used to look into +TABLE+ and
227
- # retrieve the applicable attributes.
228
- #
229
- # @return [Money::Currency]
230
- #
231
- # @example
232
- # Money::Currency.find(:eur) #=> #<Money::Currency id: eur ...>
233
- # Money::Currency.find(:foo) #=> nil
234
- def find(id)
235
- id = id.to_s.downcase.to_sym
236
- new(id) if self::TABLE[id]
237
- end
238
-
239
- # Wraps the object in a +Currency+ unless it's already a +Currency+
240
- # object.
241
- #
242
- # @param [Object] object The object to attempt and wrap as a +Currency+
243
- # object.
244
- #
245
- # @return [Money::Currency]
246
- #
247
- # @example
248
- # c1 = Money::Currency.new(:usd)
249
- # Money::Currency.wrap(nil) #=> nil
250
- # Money::Currency.wrap(c1) #=> #<Money::Currency id: usd ...>
251
- # Money::Currency.wrap("usd") #=> #<Money::Currency id: usd ...>
252
- def wrap(object)
253
- if object.nil?
254
- nil
255
- elsif object.is_a?(Currency)
256
- object
257
- else
258
- Currency.new(object)
259
- end
260
- end
261
- end
262
- end
263
- end
1
+ # encoding: utf-8
2
+
3
+ require 'json'
4
+
5
+ class Money
6
+
7
+ # Represents a specific currency unit.
8
+ class Currency
9
+ include Comparable
10
+ extend CurrencyLoader
11
+
12
+ # Thrown when an unknown currency is requested.
13
+ class UnknownCurrency < StandardError; end
14
+
15
+ # List of known currencies.
16
+ #
17
+ # == monetary unit
18
+ # The standard unit of value of a currency, as the dollar in the United States or the peso in Mexico.
19
+ # http://www.answers.com/topic/monetary-unit
20
+ # == fractional monetary unit, subunit
21
+ # A monetary unit that is valued at a fraction (usually one hundredth) of the basic monetary unit
22
+ # http://www.answers.com/topic/fractional-monetary-unit-subunit
23
+ #
24
+ # See http://en.wikipedia.org/wiki/List_of_circulating_currencies and
25
+ # http://search.cpan.org/~tnguyen/Locale-Currency-Format-1.28/Format.pm
26
+
27
+ TABLE = load_currencies
28
+
29
+ # We need a string-based validator before creating an unbounded number of symbols.
30
+ # http://www.randomhacks.net/articles/2007/01/20/13-ways-of-looking-at-a-ruby-symbol#11
31
+ # https://github.com/RubyMoney/money/issues/132
32
+ STRINGIFIED_KEYS = TABLE.keys.map{|k| k.to_s.downcase }
33
+
34
+ # The symbol used to identify the currency, usually the lowercase
35
+ # +iso_code+ attribute.
36
+ #
37
+ # @return [Symbol]
38
+ attr_reader :id
39
+
40
+ # A numerical value you can use to sort/group the currency list.
41
+ #
42
+ # @return [Integer]
43
+ attr_reader :priority
44
+
45
+ # The international 3-letter code as defined by the ISO 4217 standard.
46
+ #
47
+ # @return [String]
48
+ attr_reader :iso_code
49
+ #
50
+ # The international 3-numeric code as defined by the ISO 4217 standard.
51
+ #
52
+ # @return [String]
53
+ attr_reader :iso_numeric
54
+
55
+ # The currency name.
56
+ #
57
+ # @return [String]
58
+ attr_reader :name
59
+
60
+ # The currency symbol (UTF-8 encoded).
61
+ #
62
+ # @return [String]
63
+ attr_reader :symbol
64
+
65
+ # The html entity for the currency symbol
66
+ #
67
+ # @return [String]
68
+ attr_reader :html_entity
69
+
70
+ # The name of the fractional monetary unit.
71
+ #
72
+ # @return [String]
73
+ attr_reader :subunit
74
+
75
+ # The proportion between the unit and the subunit
76
+ #
77
+ # @return [Integer]
78
+ attr_reader :subunit_to_unit
79
+
80
+ # The decimal mark, or character used to separate the whole unit from the subunit.
81
+ #
82
+ # @return [String]
83
+ attr_reader :decimal_mark
84
+ alias :separator :decimal_mark
85
+
86
+ # The character used to separate thousands grouping of the whole unit.
87
+ #
88
+ # @return [String]
89
+ attr_reader :thousands_separator
90
+ alias :delimiter :thousands_separator
91
+
92
+ # Should the currency symbol precede the amount, or should it come after?
93
+ #
94
+ # @return [boolean]
95
+ attr_reader :symbol_first
96
+
97
+
98
+ class << self
99
+
100
+ # Lookup a currency with given +id+ an returns a +Currency+ instance on
101
+ # success, +nil+ otherwise.
102
+ #
103
+ # @param [String, Symbol, #to_s] id Used to look into +TABLE+ and
104
+ # retrieve the applicable attributes.
105
+ #
106
+ # @return [Money::Currency]
107
+ #
108
+ # @example
109
+ # Money::Currency.find(:eur) #=> #<Money::Currency id: eur ...>
110
+ # Money::Currency.find(:foo) #=> nil
111
+ def find(id)
112
+ id = id.to_s.downcase.to_sym
113
+ new(id) if self::TABLE[id]
114
+ end
115
+
116
+ # Wraps the object in a +Currency+ unless it's already a +Currency+
117
+ # object.
118
+ #
119
+ # @param [Object] object The object to attempt and wrap as a +Currency+
120
+ # object.
121
+ #
122
+ # @return [Money::Currency]
123
+ #
124
+ # @example
125
+ # c1 = Money::Currency.new(:usd)
126
+ # Money::Currency.wrap(nil) #=> nil
127
+ # Money::Currency.wrap(c1) #=> #<Money::Currency id: usd ...>
128
+ # Money::Currency.wrap("usd") #=> #<Money::Currency id: usd ...>
129
+ def wrap(object)
130
+ if object.nil?
131
+ nil
132
+ elsif object.is_a?(Currency)
133
+ object
134
+ else
135
+ Currency.new(object)
136
+ end
137
+ end
138
+ end
139
+
140
+
141
+ # Create a new +Currency+ object.
142
+ #
143
+ # @param [String, Symbol, #to_s] id Used to look into +TABLE+ and retrieve
144
+ # the applicable attributes.
145
+ #
146
+ # @return [Money::Currency]
147
+ #
148
+ # @example
149
+ # Money::Currency.new(:usd) #=> #<Money::Currency id: usd ...>
150
+ def initialize(id)
151
+ id = id.to_s.downcase
152
+ raise(UnknownCurrency, "Unknown currency `#{id}'") unless STRINGIFIED_KEYS.include?(id)
153
+
154
+ @id = id.to_sym
155
+ data = TABLE[@id]
156
+ data.each_pair do |key, value|
157
+ instance_variable_set(:"@#{key}", value)
158
+ end
159
+ end
160
+
161
+ # Compares +self+ with +other_currency+ against the value of +priority+
162
+ # attribute.
163
+ #
164
+ # @param [Money::Currency] other_currency The currency to compare to.
165
+ #
166
+ # @return [-1,0,1] -1 if less than, 0 is equal to, 1 if greater than
167
+ #
168
+ # @example
169
+ # c1 = Money::Currency.new(:usd)
170
+ # c2 = Money::Currency.new(:jpy)
171
+ # c1 <=> c2 #=> 1
172
+ # c2 <=> c1 #=> -1
173
+ # c1 <=> c1 #=> 0
174
+ def <=>(other_currency)
175
+ self.priority <=> other_currency.priority
176
+ end
177
+
178
+ # Compares +self+ with +other_currency+ and returns +true+ if the are the
179
+ # same or if their +id+ attributes match.
180
+ #
181
+ # @param [Money::Currency] other_currency The currency to compare to.
182
+ #
183
+ # @return [Boolean]
184
+ #
185
+ # @example
186
+ # c1 = Money::Currency.new(:usd)
187
+ # c2 = Money::Currency.new(:jpy)
188
+ # c1 == c1 #=> true
189
+ # c1 == c2 #=> false
190
+ def ==(other_currency)
191
+ self.equal?(other_currency) ||
192
+ self.id == other_currency.id
193
+ end
194
+
195
+ # Compares +self+ with +other_currency+ and returns +true+ if the are the
196
+ # same or if their +id+ attributes match.
197
+ #
198
+ # @param [Money::Currency] other_currency The currency to compare to.
199
+ #
200
+ # @return [Boolean]
201
+ #
202
+ # @example
203
+ # c1 = Money::Currency.new(:usd)
204
+ # c2 = Money::Currency.new(:jpy)
205
+ # c1.eql? c1 #=> true
206
+ # c1.eql? c2 #=> false
207
+ def eql?(other_currency)
208
+ self == other_currency
209
+ end
210
+
211
+ # Returns a Fixnum hash value based on the +id+ attribute in order to use
212
+ # functions like & (intersection), group_by, etc.
213
+ #
214
+ # @return [Fixnum]
215
+ #
216
+ # @example
217
+ # Money::Currency.new(:usd).hash #=> 428936
218
+ def hash
219
+ id.hash
220
+ end
221
+
222
+ # Returns a human readable representation.
223
+ #
224
+ # @return [String]
225
+ #
226
+ # @example
227
+ # Money::Currency.new(:usd) #=> #<Currency id: usd ...>
228
+ def inspect
229
+ "#<#{self.class.name} id: #{id}, priority: #{priority}, symbol_first: #{symbol_first}, thousands_separator: #{thousands_separator}, html_entity: #{html_entity}, decimal_mark: #{decimal_mark}, name: #{name}, symbol: #{symbol}, subunit_to_unit: #{subunit_to_unit}, iso_code: #{iso_code}, iso_numeric: #{iso_numeric}, subunit: #{subunit}>"
230
+ end
231
+
232
+ # Returns a string representation corresponding to the upcase +id+
233
+ # attribute.
234
+ #
235
+ # -–
236
+ # DEV: id.to_s.upcase corresponds to iso_code but don't use ISO_CODE for consistency.
237
+ #
238
+ # @return [String]
239
+ #
240
+ # @example
241
+ # Money::Currency.new(:usd).to_s #=> "USD"
242
+ # Money::Currency.new(:eur).to_s #=> "EUR"
243
+ def to_s
244
+ id.to_s.upcase
245
+ end
246
+
247
+ # Conversation to +self+.
248
+ #
249
+ # @return [self]
250
+ def to_currency
251
+ self
252
+ end
253
+
254
+
255
+ # Returns currency symbol or iso code for currencies with no symbol.
256
+ #
257
+ # @return [String]
258
+ def code
259
+ symbol || iso_code
260
+ end
261
+
262
+ def symbol_first?
263
+ !!@symbol_first
264
+ end
265
+
266
+ # The number of decimal places needed.
267
+ #
268
+ # @return [Integer]
269
+ def decimal_places
270
+ if subunit_to_unit == 1
271
+ 0
272
+ elsif subunit_to_unit % 10 == 0
273
+ Math.log10(subunit_to_unit).to_s.to_i
274
+ else
275
+ Math.log10(subunit_to_unit).to_s.to_i+1
276
+ end
277
+ end
278
+
279
+ end
280
+ end