simple_money 0.1.0 → 0.1.1
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 +19 -1
- data/README.md +10 -3
- data/lib/simple_money/money.rb +97 -35
- metadata +54 -54
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
SimpleMoney 0.1.1
|
2
|
+
=================
|
3
|
+
|
4
|
+
Features
|
5
|
+
--------
|
6
|
+
- Ensure all calculations are done using BigDecimal
|
7
|
+
- Implemented Money#to_s
|
8
|
+
- Cleaned up documentation
|
9
|
+
- Reorganize lib/spec for compatibility with autotest
|
10
|
+
- Implemented Money.overflow=
|
11
|
+
|
12
|
+
Bug fixes
|
13
|
+
---------
|
14
|
+
- Fixed error where overflow wasn't properly updated after calling Money#/
|
15
|
+
|
1
16
|
SimpleMoney 0.1.0
|
2
|
-
|
17
|
+
=================
|
18
|
+
|
19
|
+
Features
|
20
|
+
--------
|
3
21
|
- Initial release.
|
data/README.md
CHANGED
@@ -10,10 +10,17 @@ Usage:
|
|
10
10
|
require 'simple_money'
|
11
11
|
|
12
12
|
a = Money.new(1_00, :as => :cents)
|
13
|
-
a.cents
|
13
|
+
a.cents #=> 100
|
14
14
|
b = a * 1.555
|
15
|
-
b.cents
|
16
|
-
Money.overflow
|
15
|
+
b.cents #=> 156
|
16
|
+
Money.overflow #=> #<BigDecimal:... '-0.5E0',4(16)>
|
17
|
+
b.to_s #=> "100"
|
18
|
+
b.to_s(:as => :decimal) #=> "1.00"
|
19
|
+
|
20
|
+
Version History
|
21
|
+
---------------
|
22
|
+
|
23
|
+
See {file:CHANGELOG.md} for details.
|
17
24
|
|
18
25
|
Copyright
|
19
26
|
---------
|
data/lib/simple_money/money.rb
CHANGED
@@ -8,17 +8,17 @@ class Money
|
|
8
8
|
class << self
|
9
9
|
|
10
10
|
##
|
11
|
-
# The valid values for
|
11
|
+
# The valid values for as
|
12
12
|
VALID_AS_VALUES = [:cents, :decimal]
|
13
13
|
|
14
14
|
##
|
15
|
-
# The valid
|
15
|
+
# The valid rounding methods
|
16
16
|
VALID_ROUNDING_METHOD_VALUES = [:away_from_zero, :toward_zero,
|
17
17
|
:nearest_up, :nearest_down, :bankers, :up, :down]
|
18
18
|
|
19
19
|
##
|
20
20
|
# Translations from SimpleMoney rounding methods to BigDecimal rounding
|
21
|
-
#
|
21
|
+
# methods.
|
22
22
|
ROUNDING_METHOD_TRANSLATION = {
|
23
23
|
:away_from_zero => BigDecimal::ROUND_UP,
|
24
24
|
:toward_zero => BigDecimal::ROUND_DOWN,
|
@@ -30,12 +30,12 @@ class Money
|
|
30
30
|
}
|
31
31
|
|
32
32
|
##
|
33
|
-
# @return [Symbol] The default
|
33
|
+
# @return [Symbol] The default as used to create a new Money (defaults to
|
34
34
|
# :cents).
|
35
35
|
attr_reader :default_as
|
36
36
|
|
37
37
|
##
|
38
|
-
# Set the default
|
38
|
+
# Set the default as used to create a new Money.
|
39
39
|
#
|
40
40
|
# @param [Symbol] as The default to use.
|
41
41
|
#
|
@@ -68,13 +68,13 @@ class Money
|
|
68
68
|
end
|
69
69
|
|
70
70
|
##
|
71
|
-
# @return [Symbol] The default
|
72
|
-
# not result in an
|
71
|
+
# @return [Symbol] The default rounding method used when calculations do
|
72
|
+
# not result in an Fixnum (defaults to :bankers).
|
73
73
|
attr_reader :default_rounding_method
|
74
74
|
|
75
75
|
##
|
76
|
-
# Set the default
|
77
|
-
#
|
76
|
+
# Set the default rounding method used when calculations do not result in a
|
77
|
+
# Fixnum.
|
78
78
|
#
|
79
79
|
# @param [Symbol] rounding_method The default to use.
|
80
80
|
#
|
@@ -94,8 +94,7 @@ class Money
|
|
94
94
|
end
|
95
95
|
|
96
96
|
##
|
97
|
-
# Returns true if argument is a valid
|
98
|
-
# false.
|
97
|
+
# Returns true if argument is a valid rounding method, otherwise false.
|
99
98
|
#
|
100
99
|
# @param [Symbol] rounding_method The value to check.
|
101
100
|
#
|
@@ -110,29 +109,46 @@ class Money
|
|
110
109
|
|
111
110
|
##
|
112
111
|
# @return [BigDecimal] The factional cents left over from any transactions
|
113
|
-
# that
|
112
|
+
# that overflowed.
|
114
113
|
attr_reader :overflow
|
115
114
|
|
115
|
+
##
|
116
|
+
# Update the overflow to the specified amount (converted to a BigDecimal
|
117
|
+
# object).
|
118
|
+
#
|
119
|
+
# @param [#to_s] n The value to set the overflow to.
|
120
|
+
#
|
121
|
+
# @return [BigDecimal]
|
122
|
+
#
|
123
|
+
# @example
|
124
|
+
# Money.round(1.5)
|
125
|
+
# Money.overflow #=> #<BigDecimal:... '-0.5E0',4(16)>
|
126
|
+
# Money.overflow = 0
|
127
|
+
# Money.overflow #=> #<BigDecimal:... '0.0',4(8)>
|
128
|
+
def overflow=(n)
|
129
|
+
@overflow = BigDecimal(n.to_s)
|
130
|
+
end
|
131
|
+
|
116
132
|
##
|
117
133
|
# Resets the overflow bucket to 0.
|
118
134
|
#
|
119
135
|
# @return [BigDecimal]
|
120
136
|
def reset_overflow
|
121
|
-
|
137
|
+
self.overflow = 0
|
122
138
|
end
|
123
139
|
|
124
140
|
##
|
125
141
|
# Returns n rounded to an integer using the given rounding method, or the
|
126
142
|
# default rounding method when none is provided. When rounding, the
|
127
|
-
# fractional cents are added to
|
143
|
+
# fractional cents are added to the overflow bucket.
|
128
144
|
#
|
129
145
|
# @param [#to_s] n The value to round.
|
130
146
|
# @param [Symbol] rounding_method The rounding method to use.
|
131
147
|
#
|
132
148
|
# @return [Fixnum]
|
133
149
|
#
|
134
|
-
# @raise [ArgumentError] Will raise an
|
135
|
-
#
|
150
|
+
# @raise [ArgumentError] Will raise an ArgumentError if an invalid rounding
|
151
|
+
# method is given.
|
136
152
|
#
|
137
153
|
# @example
|
138
154
|
# Money.round(1.5, :bankers) #=> 2
|
@@ -165,17 +181,17 @@ class Money
|
|
165
181
|
attr_reader :rounding_method
|
166
182
|
|
167
183
|
##
|
168
|
-
# Creates a new Money. If
|
169
|
-
#
|
184
|
+
# Creates a new Money object. If as is set to :cents, n will be coerced to a
|
185
|
+
# Fixnum. If as is set to :decimal, n will be coerced to a BigDecimal.
|
170
186
|
#
|
171
187
|
# @param [#to_s] n Value of the new object.
|
172
|
-
# @param [Hash] options options used to build the new object.
|
188
|
+
# @param [Hash] options The options used to build the new object.
|
173
189
|
# @option options [Symbol] :as How n is represented (defaults to
|
174
|
-
# self.class.default_as).
|
190
|
+
# self.class.default_as).
|
175
191
|
# @option options [Symbol] :rounding_method How any calculations resulting in
|
176
192
|
# fractions of a cent should be rounded.
|
177
193
|
#
|
178
|
-
# @raise [ArgumentError] Will raise an ArgumentError if
|
194
|
+
# @raise [ArgumentError] Will raise an ArgumentError if as is not valid.
|
179
195
|
#
|
180
196
|
# @example
|
181
197
|
# Money.new #=> #<Money:... @cents: 0>
|
@@ -202,20 +218,26 @@ class Money
|
|
202
218
|
|
203
219
|
@cents = case options[:as]
|
204
220
|
when :cents
|
205
|
-
Money.round(
|
221
|
+
Money.round(
|
222
|
+
BigDecimal(n.to_s), rounding_method
|
223
|
+
)
|
206
224
|
when :decimal
|
207
|
-
Money.round(
|
225
|
+
Money.round(
|
226
|
+
BigDecimal(n.to_s) * BigDecimal("100"),
|
227
|
+
rounding_method
|
228
|
+
)
|
208
229
|
end
|
209
230
|
end
|
210
231
|
|
211
232
|
##
|
212
|
-
# Add two Money objects; return the results as a new Money.
|
233
|
+
# Add two Money objects; return the results as a new Money object.
|
213
234
|
#
|
214
235
|
# @param [Money] n The object to add.
|
215
236
|
#
|
216
237
|
# @return [Money]
|
217
238
|
#
|
218
|
-
# @raise [ArgumentError] Will raise an ArgumentError unless n is a Money
|
239
|
+
# @raise [ArgumentError] Will raise an ArgumentError unless n is a Money
|
240
|
+
# object.
|
219
241
|
#
|
220
242
|
# @example
|
221
243
|
# Money.new(1) + Money.new(2) #=> #<Money:... @cents: 3>
|
@@ -225,13 +247,14 @@ class Money
|
|
225
247
|
end
|
226
248
|
|
227
249
|
##
|
228
|
-
# Subtract two Money; return the results as a new Money.
|
250
|
+
# Subtract two Money; return the results as a new Money object.
|
229
251
|
#
|
230
252
|
# @param [Money] n The object to subtract.
|
231
253
|
#
|
232
254
|
# @return [Money]
|
233
255
|
#
|
234
|
-
# @raise [ArgumentError] Will raise an ArgumentError unless n is a Money
|
256
|
+
# @raise [ArgumentError] Will raise an ArgumentError unless n is a Money
|
257
|
+
# object.
|
235
258
|
#
|
236
259
|
# @example
|
237
260
|
# Money.new(2) - Money.new(1) #=> #<Money:... @cents: 1>
|
@@ -241,34 +264,37 @@ class Money
|
|
241
264
|
end
|
242
265
|
|
243
266
|
##
|
244
|
-
# Multiply Money by a Numeric; return the results as a new Money.
|
267
|
+
# Multiply Money by a Numeric; return the results as a new Money object.
|
245
268
|
#
|
246
269
|
# @param [Numeric] n The object to multiply. n will be coerced to a
|
247
270
|
# BigDecimal before any calculations are done.
|
248
271
|
#
|
249
272
|
# @return [Money]
|
250
273
|
#
|
251
|
-
# @raise [ArgumentError] Will raise an ArgumentError unless n is a Numeric
|
274
|
+
# @raise [ArgumentError] Will raise an ArgumentError unless n is a Numeric
|
275
|
+
# object.
|
252
276
|
#
|
253
277
|
# @example
|
254
278
|
# Money.new(2) * 2 #=> #<Money:... @cents: 4>
|
255
279
|
def *(n)
|
256
280
|
raise ArgumentError, "n must be a Numeric" unless n.is_a? Numeric
|
257
281
|
|
258
|
-
Money.new(
|
282
|
+
Money.new(
|
283
|
+
BigDecimal(self.cents.to_s) * BigDecimal(n.to_s),
|
284
|
+
:as => :cents
|
285
|
+
)
|
259
286
|
end
|
260
287
|
|
261
288
|
##
|
262
|
-
# Divide
|
263
|
-
# Numeric/Money.
|
289
|
+
# Divide self by a Money/Numeric; return the results as a new Numeric/Money.
|
264
290
|
#
|
265
291
|
# @param [Money,Numeric] n The object to divide. If n is Numeric, it will be
|
266
292
|
# coerced to a BigDecimal before any calculations are done.
|
267
293
|
#
|
268
294
|
# @return [Numeric,Money]
|
269
295
|
#
|
270
|
-
# @raise [ArgumentError] Will raise an ArgumentError unless n is a Money
|
271
|
-
# Numeric.
|
296
|
+
# @raise [ArgumentError] Will raise an ArgumentError unless n is a Money
|
297
|
+
# object or Numeric.
|
272
298
|
#
|
273
299
|
# @example
|
274
300
|
# Money.new(10) / Money.new(5) #=> 2
|
@@ -278,10 +304,46 @@ class Money
|
|
278
304
|
when Money
|
279
305
|
BigDecimal(self.cents.to_s) / BigDecimal(n.cents.to_s)
|
280
306
|
when Numeric
|
281
|
-
|
307
|
+
result, overflow = BigDecimal(self.cents.to_s).divmod(BigDecimal(n.to_s))
|
308
|
+
self.class.overflow = self.class.overflow + overflow
|
309
|
+
Money.new(result, :as => :cents)
|
282
310
|
else
|
283
311
|
raise ArgumentError, "n must be a Money or Numeric"
|
284
312
|
end
|
285
313
|
end
|
286
314
|
|
315
|
+
##
|
316
|
+
# Returns cents formatted as a string, based on any options passed.
|
317
|
+
#
|
318
|
+
# @param [Hash] options The options used to format the string.
|
319
|
+
# @option options [Symbol] :as How cents should be returned (defaults to
|
320
|
+
# self.class.default_as).
|
321
|
+
#
|
322
|
+
# @return [String]
|
323
|
+
#
|
324
|
+
# @raise [ArgumentError] Will raise an ArgumentError if as is not valid.
|
325
|
+
#
|
326
|
+
# @example
|
327
|
+
# n = Money.new(1_00, :as => :cents)
|
328
|
+
# n.to_s #=> "100"
|
329
|
+
# n.to_s(:as => :decimal) #=> "1.00"
|
330
|
+
def to_s(options = {})
|
331
|
+
options = {
|
332
|
+
:as => :cents
|
333
|
+
}.merge(options)
|
334
|
+
|
335
|
+
raise ArgumentError, "invalid `as`" unless (
|
336
|
+
self.class.valid_as? options[:as]
|
337
|
+
)
|
338
|
+
|
339
|
+
case options[:as]
|
340
|
+
when :cents
|
341
|
+
cents.to_s
|
342
|
+
when :decimal
|
343
|
+
unit, subunit = cents.divmod(100).map(&:to_s)
|
344
|
+
subunit = "0#{subunit}"[-2,2]
|
345
|
+
"#{unit}.#{subunit}"
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
287
349
|
end
|
metadata
CHANGED
@@ -3,48 +3,48 @@ name: simple_money
|
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
version: 0.1.
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
version: 0.1.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
|
-
- Shane Emmons
|
12
|
+
- Shane Emmons
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-01-
|
17
|
+
date: 2011-01-10 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 2
|
30
|
+
- 0
|
31
|
+
- 0
|
32
|
+
version: 2.0.0
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: yard
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :development
|
47
|
+
version_requirements: *id002
|
48
48
|
description: This gem is intended for working with financial calculations where you need highly accurate results.
|
49
49
|
email: semmons99@gmail.com
|
50
50
|
executables: []
|
@@ -54,11 +54,11 @@ extensions: []
|
|
54
54
|
extra_rdoc_files: []
|
55
55
|
|
56
56
|
files:
|
57
|
-
- lib/simple_money
|
58
|
-
- lib/simple_money.rb
|
59
|
-
- CHANGELOG.md
|
60
|
-
- LICENSE
|
61
|
-
- README.md
|
57
|
+
- lib/simple_money.rb
|
58
|
+
- lib/simple_money/money.rb
|
59
|
+
- CHANGELOG.md
|
60
|
+
- LICENSE
|
61
|
+
- README.md
|
62
62
|
has_rdoc: true
|
63
63
|
homepage: http://github.com/semmons99/simple_money
|
64
64
|
licenses: []
|
@@ -67,27 +67,27 @@ post_install_message:
|
|
67
67
|
rdoc_options: []
|
68
68
|
|
69
69
|
require_paths:
|
70
|
-
- lib
|
70
|
+
- lib
|
71
71
|
required_ruby_version: !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
segments:
|
77
|
+
- 1
|
78
|
+
- 8
|
79
|
+
- 7
|
80
|
+
version: 1.8.7
|
81
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
82
|
none: false
|
83
83
|
requirements:
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
segments:
|
87
|
+
- 1
|
88
|
+
- 3
|
89
|
+
- 7
|
90
|
+
version: 1.3.7
|
91
91
|
requirements: []
|
92
92
|
|
93
93
|
rubyforge_project:
|