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.
- data/CHANGELOG.md +405 -391
- data/LICENSE +21 -21
- data/README.md +249 -243
- data/Rakefile +52 -49
- data/config/currency.json +2068 -2068
- data/config/currency_bc.json +41 -41
- data/lib/money.rb +28 -28
- data/lib/money/bank/base.rb +130 -131
- data/lib/money/bank/variable_exchange.rb +253 -252
- data/lib/money/core_extensions.rb +82 -82
- data/lib/money/currency.rb +280 -263
- data/lib/money/currency_loader.rb +21 -19
- data/lib/money/money.rb +411 -405
- data/lib/money/money/arithmetic.rb +257 -246
- data/lib/money/money/formatting.rb +251 -260
- data/lib/money/money/parsing.rb +350 -350
- data/money.gemspec +29 -29
- data/spec/bank/base_spec.rb +69 -72
- data/spec/bank/variable_exchange_spec.rb +233 -238
- data/spec/core_extensions_spec.rb +160 -158
- data/spec/currency_spec.rb +139 -120
- data/spec/money/arithmetic_spec.rb +482 -479
- data/spec/money/formatting_spec.rb +402 -383
- data/spec/money/parsing_spec.rb +210 -197
- data/spec/money_spec.rb +312 -292
- data/spec/spec_helper.rb +32 -28
- metadata +14 -14
@@ -1,246 +1,257 @@
|
|
1
|
-
class Money
|
2
|
-
module Arithmetic
|
3
|
-
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# @
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
#
|
25
|
-
#
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
#
|
97
|
-
#
|
98
|
-
#
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
#
|
108
|
-
#
|
109
|
-
#
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
#
|
119
|
-
#
|
120
|
-
#
|
121
|
-
#
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
#
|
148
|
-
#
|
149
|
-
#
|
150
|
-
# @
|
151
|
-
#
|
152
|
-
# @
|
153
|
-
#
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
#
|
182
|
-
#
|
183
|
-
# @
|
184
|
-
#
|
185
|
-
# @
|
186
|
-
#
|
187
|
-
# @
|
188
|
-
def
|
189
|
-
self.
|
190
|
-
end
|
191
|
-
|
192
|
-
#
|
193
|
-
#
|
194
|
-
# @param [Money, Fixnum] val Number
|
195
|
-
#
|
196
|
-
# @return [Money]
|
197
|
-
#
|
198
|
-
# @
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
#
|
224
|
-
#
|
225
|
-
#
|
226
|
-
#
|
227
|
-
#
|
228
|
-
# Money.new(
|
229
|
-
def
|
230
|
-
cents
|
231
|
-
end
|
232
|
-
|
233
|
-
# Test if the money amount is
|
234
|
-
#
|
235
|
-
#
|
236
|
-
#
|
237
|
-
#
|
238
|
-
#
|
239
|
-
# Money.new(
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
1
|
+
class Money
|
2
|
+
module Arithmetic
|
3
|
+
|
4
|
+
# Returns a money object with changed polarity.
|
5
|
+
#
|
6
|
+
# @return [Money]
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# - Money.new(100) #=> #<Money @cents=-100>
|
10
|
+
def -@
|
11
|
+
Money.new(-cents, currency)
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
# Checks whether two money objects have the same currency and the same
|
16
|
+
# amount. Checks against money objects with a different currency and checks
|
17
|
+
# against objects that do not respond to #to_money will always return false.
|
18
|
+
#
|
19
|
+
# @param [Money] other_money Value to compare with.
|
20
|
+
#
|
21
|
+
# @return [Boolean]
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# Money.new(100) == Money.new(101) #=> false
|
25
|
+
# Money.new(100) == Money.new(100) #=> true
|
26
|
+
def ==(other_money)
|
27
|
+
if other_money.respond_to?(:to_money)
|
28
|
+
other_money = other_money.to_money
|
29
|
+
cents == other_money.cents && self.currency == other_money.currency
|
30
|
+
else
|
31
|
+
false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Synonymous with +#==+.
|
36
|
+
#
|
37
|
+
# @param [Money] other_money Value to compare with.
|
38
|
+
#
|
39
|
+
# @return [Money]
|
40
|
+
#
|
41
|
+
# @see #==
|
42
|
+
def eql?(other_money)
|
43
|
+
self == other_money
|
44
|
+
end
|
45
|
+
|
46
|
+
def <=>(other_money)
|
47
|
+
if other_money.respond_to?(:to_money)
|
48
|
+
other_money = other_money.to_money
|
49
|
+
if self.currency == other_money.currency
|
50
|
+
cents <=> other_money.cents
|
51
|
+
else
|
52
|
+
cents <=> other_money.exchange_to(currency).cents
|
53
|
+
end
|
54
|
+
else
|
55
|
+
raise ArgumentError, "Comparison of #{self.class} with #{other_money.inspect} failed"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns a new Money object containing the sum of the two operands' monetary
|
60
|
+
# values. If +other_money+ has a different currency then its monetary value
|
61
|
+
# is automatically exchanged to this object's currency using +exchange_to+.
|
62
|
+
#
|
63
|
+
# @param [Money] other_money Other +Money+ object to add.
|
64
|
+
#
|
65
|
+
# @return [Money]
|
66
|
+
#
|
67
|
+
# @example
|
68
|
+
# Money.new(100) + Money.new(100) #=> #<Money @cents=200>
|
69
|
+
def +(other_money)
|
70
|
+
if currency == other_money.currency
|
71
|
+
Money.new(cents + other_money.cents, other_money.currency)
|
72
|
+
else
|
73
|
+
Money.new(cents + other_money.exchange_to(currency).cents, currency)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns a new Money object containing the difference between the two
|
78
|
+
# operands' monetary values. If +other_money+ has a different currency then
|
79
|
+
# its monetary value is automatically exchanged to this object's currency
|
80
|
+
# using +exchange_to+.
|
81
|
+
#
|
82
|
+
# @param [Money] other_money Other +Money+ object to subtract.
|
83
|
+
#
|
84
|
+
# @return [Money]
|
85
|
+
#
|
86
|
+
# @example
|
87
|
+
# Money.new(100) - Money.new(99) #=> #<Money @cents=1>
|
88
|
+
def -(other_money)
|
89
|
+
if currency == other_money.currency
|
90
|
+
Money.new(cents - other_money.cents, other_money.currency)
|
91
|
+
else
|
92
|
+
Money.new(cents - other_money.exchange_to(currency).cents, currency)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Multiplies the monetary value with the given number and returns a new
|
97
|
+
# +Money+ object with this monetary value and the same currency.
|
98
|
+
#
|
99
|
+
# Note that you can't multiply a Money object by an other +Money+ object.
|
100
|
+
#
|
101
|
+
# @param [Numeric] value Number to multiply by.
|
102
|
+
#
|
103
|
+
# @return [Money] The resulting money.
|
104
|
+
#
|
105
|
+
# @raise [ArgumentError] If +value+ is a Money instance.
|
106
|
+
#
|
107
|
+
# @example
|
108
|
+
# Money.new(100) * 2 #=> #<Money @cents=200>
|
109
|
+
#
|
110
|
+
def *(value)
|
111
|
+
if value.is_a?(Money)
|
112
|
+
raise ArgumentError, "Can't multiply a Money by a Money"
|
113
|
+
else
|
114
|
+
Money.new(cents * value, currency)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Divides the monetary value with the given number and returns a new +Money+
|
119
|
+
# object with this monetary value and the same currency.
|
120
|
+
# Can also divide by another +Money+ object to get a ratio.
|
121
|
+
#
|
122
|
+
# +Money/Numeric+ returns +Money+. +Money/Money+ returns +Float+.
|
123
|
+
#
|
124
|
+
# @param [Money, Numeric] value Number to divide by.
|
125
|
+
#
|
126
|
+
# @return [Money] The resulting money if you divide Money by a number.
|
127
|
+
# @return [Float] The resulting number if you divide Money by a Money.
|
128
|
+
#
|
129
|
+
# @example
|
130
|
+
# Money.new(100) / 10 #=> #<Money @cents=10>
|
131
|
+
# Money.new(100) / Money.new(10) #=> 10.0
|
132
|
+
#
|
133
|
+
def /(value)
|
134
|
+
if value.is_a?(Money)
|
135
|
+
if currency == value.currency
|
136
|
+
(cents / BigDecimal.new(value.cents.to_s)).to_f
|
137
|
+
else
|
138
|
+
(cents / BigDecimal(value.exchange_to(currency).cents.to_s)).to_f
|
139
|
+
end
|
140
|
+
else
|
141
|
+
Money.new(cents / value, currency)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# Synonym for +#/+.
|
146
|
+
#
|
147
|
+
# @param [Money, Numeric] value Number to divide by.
|
148
|
+
#
|
149
|
+
# @return [Money] The resulting money if you divide Money by a number.
|
150
|
+
# @return [Float] The resulting number if you divide Money by a Money.
|
151
|
+
#
|
152
|
+
# @see #/
|
153
|
+
#
|
154
|
+
def div(value)
|
155
|
+
self / value
|
156
|
+
end
|
157
|
+
|
158
|
+
# Divide money by money or fixnum and return array containing quotient and
|
159
|
+
# modulus.
|
160
|
+
#
|
161
|
+
# @param [Money, Fixnum] val Number to divmod by.
|
162
|
+
#
|
163
|
+
# @return [Array<Money,Money>,Array<Fixnum,Money>]
|
164
|
+
#
|
165
|
+
# @example
|
166
|
+
# Money.new(100).divmod(9) #=> [#<Money @cents=11>, #<Money @cents=1>]
|
167
|
+
# Money.new(100).divmod(Money.new(9)) #=> [11, #<Money @cents=1>]
|
168
|
+
def divmod(val)
|
169
|
+
if val.is_a?(Money)
|
170
|
+
a = self.cents
|
171
|
+
b = self.currency == val.currency ? val.cents : val.exchange_to(self.currency).cents
|
172
|
+
q, m = a.divmod(b)
|
173
|
+
return [q, Money.new(m, self.currency)]
|
174
|
+
else
|
175
|
+
return [self.div(val), Money.new(self.cents.modulo(val), self.currency)]
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# Equivalent to +self.divmod(val)[1]+
|
180
|
+
#
|
181
|
+
# @param [Money, Fixnum] val Number take modulo with.
|
182
|
+
#
|
183
|
+
# @return [Money]
|
184
|
+
#
|
185
|
+
# @example
|
186
|
+
# Money.new(100).modulo(9) #=> #<Money @cents=1>
|
187
|
+
# Money.new(100).modulo(Money.new(9)) #=> #<Money @cents=1>
|
188
|
+
def modulo(val)
|
189
|
+
self.divmod(val)[1]
|
190
|
+
end
|
191
|
+
|
192
|
+
# Synonym for +#modulo+.
|
193
|
+
#
|
194
|
+
# @param [Money, Fixnum] val Number take modulo with.
|
195
|
+
#
|
196
|
+
# @return [Money]
|
197
|
+
#
|
198
|
+
# @see #modulo
|
199
|
+
def %(val)
|
200
|
+
self.modulo(val)
|
201
|
+
end
|
202
|
+
|
203
|
+
# If different signs +self.modulo(val) - val+ otherwise +self.modulo(val)+
|
204
|
+
#
|
205
|
+
# @param [Money, Fixnum] val Number to rake remainder with.
|
206
|
+
#
|
207
|
+
# @return [Money]
|
208
|
+
#
|
209
|
+
# @example
|
210
|
+
# Money.new(100).remainder(9) #=> #<Money @cents=1>
|
211
|
+
def remainder(val)
|
212
|
+
a, b = self, val
|
213
|
+
b = b.exchange_to(a.currency) if b.is_a?(Money) and a.currency != b.currency
|
214
|
+
|
215
|
+
a_sign, b_sign = :pos, :pos
|
216
|
+
a_sign = :neg if a.cents < 0
|
217
|
+
b_sign = :neg if (b.is_a?(Money) and b.cents < 0) or (b < 0)
|
218
|
+
|
219
|
+
return a.modulo(b) if a_sign == b_sign
|
220
|
+
a.modulo(b) - (b.is_a?(Money) ? b : Money.new(b, a.currency))
|
221
|
+
end
|
222
|
+
|
223
|
+
# Return absolute value of self as a new Money object.
|
224
|
+
#
|
225
|
+
# @return [Money]
|
226
|
+
#
|
227
|
+
# @example
|
228
|
+
# Money.new(-100).abs #=> #<Money @cents=100>
|
229
|
+
def abs
|
230
|
+
Money.new(self.cents.abs, self.currency)
|
231
|
+
end
|
232
|
+
|
233
|
+
# Test if the money amount is zero.
|
234
|
+
#
|
235
|
+
# @return [Boolean]
|
236
|
+
#
|
237
|
+
# @example
|
238
|
+
# Money.new(100).zero? #=> false
|
239
|
+
# Money.new(0).zero? #=> true
|
240
|
+
def zero?
|
241
|
+
cents == 0
|
242
|
+
end
|
243
|
+
|
244
|
+
# Test if the money amount is non-zero. Returns this money object if it is
|
245
|
+
# non-zero, or nil otherwise, like +Numeric#nonzero?+.
|
246
|
+
#
|
247
|
+
# @return [Money, nil]
|
248
|
+
#
|
249
|
+
# @example
|
250
|
+
# Money.new(100).nonzero? #=> #<Money @cents=100>
|
251
|
+
# Money.new(0).nonzero? #=> nil
|
252
|
+
def nonzero?
|
253
|
+
cents != 0 ? self : nil
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
end
|