money 4.0.1 → 4.0.2

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.
@@ -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