minting 1.8.2 → 1.9.0
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.
- checksums.yaml +4 -4
- data/README.md +26 -9
- data/bin/bench_check +34 -9
- data/doc/Mint/Currency.html +66 -33
- data/doc/Mint/Money.html +491 -240
- data/doc/Mint/RangeStepPatch.html +1 -1
- data/doc/Mint/Registry.html +7 -3
- data/doc/Mint/Rounding.html +25 -14
- data/doc/Mint/UnknownCurrency.html +1 -1
- data/doc/Mint.html +18 -7
- data/doc/Minting.html +2 -2
- data/doc/_index.html +1 -1
- data/doc/file.README.html +27 -46
- data/doc/index.html +27 -46
- data/doc/method_list.html +51 -35
- data/doc/top-level-namespace.html +1 -1
- data/lib/minting/currency/currency.rb +6 -1
- data/lib/minting/mint/{locale_backend.rb → i18n.rb} +27 -0
- data/lib/minting/mint/mint.rb +10 -1
- data/lib/minting/mint/registry/zeros.rb +2 -0
- data/lib/minting/mint/rounding.rb +14 -1
- data/lib/minting/mint.rb +1 -2
- data/lib/minting/money/allocation/allocation.rb +1 -1
- data/lib/minting/money/allocation/split.rb +1 -1
- data/lib/minting/money/arithmetics/methods.rb +1 -1
- data/lib/minting/money/arithmetics/operators.rb +1 -1
- data/lib/minting/money/clamp.rb +2 -2
- data/lib/minting/money/coercion.rb +1 -1
- data/lib/minting/money/comparable.rb +1 -1
- data/lib/minting/money/constructors.rb +21 -11
- data/lib/minting/money/conversion.rb +1 -1
- data/lib/minting/money/format/formatting.rb +59 -29
- data/lib/minting/money/format/to_s.rb +44 -16
- data/lib/minting/money/money.rb +14 -5
- data/lib/minting/version.rb +1 -1
- metadata +2 -2
data/doc/method_list.html
CHANGED
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
|
|
146
146
|
<li class="odd ">
|
|
147
147
|
<div class="item">
|
|
148
|
-
<span class='object_link'><a href="Mint/Money.html#
|
|
148
|
+
<span class='object_link'><a href="Mint/Money.html#clamp-instance_method" title="Mint::Money#clamp (method)">#clamp</a></span>
|
|
149
149
|
<small>Mint::Money</small>
|
|
150
150
|
</div>
|
|
151
151
|
</li>
|
|
@@ -153,23 +153,23 @@
|
|
|
153
153
|
|
|
154
154
|
<li class="even ">
|
|
155
155
|
<div class="item">
|
|
156
|
-
<span class='object_link'><a href="Mint/
|
|
157
|
-
<small>Mint::
|
|
156
|
+
<span class='object_link'><a href="Mint/Currency.html#code-instance_method" title="Mint::Currency#code (method)">#code</a></span>
|
|
157
|
+
<small>Mint::Currency</small>
|
|
158
158
|
</div>
|
|
159
159
|
</li>
|
|
160
160
|
|
|
161
161
|
|
|
162
162
|
<li class="odd ">
|
|
163
163
|
<div class="item">
|
|
164
|
-
<span class='object_link'><a href="Mint/
|
|
165
|
-
<small>Mint::
|
|
164
|
+
<span class='object_link'><a href="Mint/Money.html#coerce-instance_method" title="Mint::Money#coerce (method)">#coerce</a></span>
|
|
165
|
+
<small>Mint::Money</small>
|
|
166
166
|
</div>
|
|
167
167
|
</li>
|
|
168
168
|
|
|
169
169
|
|
|
170
170
|
<li class="even ">
|
|
171
171
|
<div class="item">
|
|
172
|
-
<span class='object_link'><a href="Mint/Money.html#
|
|
172
|
+
<span class='object_link'><a href="Mint/Money.html#copy_with-instance_method" title="Mint::Money#copy_with (method)">#copy_with</a></span>
|
|
173
173
|
<small>Mint::Money</small>
|
|
174
174
|
</div>
|
|
175
175
|
</li>
|
|
@@ -289,7 +289,7 @@
|
|
|
289
289
|
|
|
290
290
|
<li class="odd ">
|
|
291
291
|
<div class="item">
|
|
292
|
-
<span class='object_link'><a href="Mint/Money.html#
|
|
292
|
+
<span class='object_link'><a href="Mint/Money.html#from_subunits-class_method" title="Mint::Money.from_subunits (method)">from_subunits</a></span>
|
|
293
293
|
<small>Mint::Money</small>
|
|
294
294
|
</div>
|
|
295
295
|
</li>
|
|
@@ -343,7 +343,7 @@
|
|
|
343
343
|
</li>
|
|
344
344
|
|
|
345
345
|
|
|
346
|
-
<li class="even ">
|
|
346
|
+
<li class="even deprecated">
|
|
347
347
|
<div class="item">
|
|
348
348
|
<span class='object_link'><a href="Mint/Money.html#mint-instance_method" title="Mint::Money#mint (method)">#mint</a></span>
|
|
349
349
|
<small>Mint::Money</small>
|
|
@@ -377,7 +377,7 @@
|
|
|
377
377
|
|
|
378
378
|
<li class="even ">
|
|
379
379
|
<div class="item">
|
|
380
|
-
<span class='object_link'><a href="Mint/Money.html#
|
|
380
|
+
<span class='object_link'><a href="Mint/Money.html#no_currency-class_method" title="Mint::Money.no_currency (method)">no_currency</a></span>
|
|
381
381
|
<small>Mint::Money</small>
|
|
382
382
|
</div>
|
|
383
383
|
</li>
|
|
@@ -385,31 +385,31 @@
|
|
|
385
385
|
|
|
386
386
|
<li class="odd ">
|
|
387
387
|
<div class="item">
|
|
388
|
-
<span class='object_link'><a href="Mint/
|
|
389
|
-
<small>Mint::
|
|
388
|
+
<span class='object_link'><a href="Mint/Money.html#nonzero%3F-instance_method" title="Mint::Money#nonzero? (method)">#nonzero?</a></span>
|
|
389
|
+
<small>Mint::Money</small>
|
|
390
390
|
</div>
|
|
391
391
|
</li>
|
|
392
392
|
|
|
393
393
|
|
|
394
394
|
<li class="even ">
|
|
395
395
|
<div class="item">
|
|
396
|
-
<span class='object_link'><a href="Mint.html#
|
|
397
|
-
<small>Mint</small>
|
|
396
|
+
<span class='object_link'><a href="Mint/Currency.html#normalize_amount-instance_method" title="Mint::Currency#normalize_amount (method)">#normalize_amount</a></span>
|
|
397
|
+
<small>Mint::Currency</small>
|
|
398
398
|
</div>
|
|
399
399
|
</li>
|
|
400
400
|
|
|
401
401
|
|
|
402
402
|
<li class="odd ">
|
|
403
403
|
<div class="item">
|
|
404
|
-
<span class='object_link'><a href="Mint
|
|
405
|
-
<small>Mint
|
|
404
|
+
<span class='object_link'><a href="Mint.html#parse-instance_method" title="Mint#parse (method)">#parse</a></span>
|
|
405
|
+
<small>Mint</small>
|
|
406
406
|
</div>
|
|
407
407
|
</li>
|
|
408
408
|
|
|
409
409
|
|
|
410
410
|
<li class="even ">
|
|
411
411
|
<div class="item">
|
|
412
|
-
<span class='object_link'><a href="Mint/Money.html#parse
|
|
412
|
+
<span class='object_link'><a href="Mint/Money.html#parse-class_method" title="Mint::Money.parse (method)">parse</a></span>
|
|
413
413
|
<small>Mint::Money</small>
|
|
414
414
|
</div>
|
|
415
415
|
</li>
|
|
@@ -425,7 +425,7 @@
|
|
|
425
425
|
|
|
426
426
|
<li class="even ">
|
|
427
427
|
<div class="item">
|
|
428
|
-
<span class='object_link'><a href="Mint/Money.html#
|
|
428
|
+
<span class='object_link'><a href="Mint/Money.html#parse!-class_method" title="Mint::Money.parse! (method)">parse!</a></span>
|
|
429
429
|
<small>Mint::Money</small>
|
|
430
430
|
</div>
|
|
431
431
|
</li>
|
|
@@ -433,16 +433,16 @@
|
|
|
433
433
|
|
|
434
434
|
<li class="odd ">
|
|
435
435
|
<div class="item">
|
|
436
|
-
<span class='object_link'><a href="Mint/
|
|
437
|
-
<small>Mint::
|
|
436
|
+
<span class='object_link'><a href="Mint/Money.html#positive%3F-instance_method" title="Mint::Money#positive? (method)">#positive?</a></span>
|
|
437
|
+
<small>Mint::Money</small>
|
|
438
438
|
</div>
|
|
439
439
|
</li>
|
|
440
440
|
|
|
441
441
|
|
|
442
442
|
<li class="even ">
|
|
443
443
|
<div class="item">
|
|
444
|
-
<span class='object_link'><a href="Mint/
|
|
445
|
-
<small>Mint::
|
|
444
|
+
<span class='object_link'><a href="Mint/Currency.html#priority-instance_method" title="Mint::Currency#priority (method)">#priority</a></span>
|
|
445
|
+
<small>Mint::Currency</small>
|
|
446
446
|
</div>
|
|
447
447
|
</li>
|
|
448
448
|
|
|
@@ -456,6 +456,14 @@
|
|
|
456
456
|
|
|
457
457
|
|
|
458
458
|
<li class="even ">
|
|
459
|
+
<div class="item">
|
|
460
|
+
<span class='object_link'><a href="Mint/Registry.html#register-class_method" title="Mint::Registry.register (method)">register</a></span>
|
|
461
|
+
<small>Mint::Registry</small>
|
|
462
|
+
</div>
|
|
463
|
+
</li>
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
<li class="odd ">
|
|
459
467
|
<div class="item">
|
|
460
468
|
<span class='object_link'><a href="Mint/Currency.html#resolve-class_method" title="Mint::Currency.resolve (method)">resolve</a></span>
|
|
461
469
|
<small>Mint::Currency</small>
|
|
@@ -463,7 +471,7 @@
|
|
|
463
471
|
</li>
|
|
464
472
|
|
|
465
473
|
|
|
466
|
-
<li class="
|
|
474
|
+
<li class="even ">
|
|
467
475
|
<div class="item">
|
|
468
476
|
<span class='object_link'><a href="Mint/Currency.html#resolve!-class_method" title="Mint::Currency.resolve! (method)">resolve!</a></span>
|
|
469
477
|
<small>Mint::Currency</small>
|
|
@@ -471,7 +479,7 @@
|
|
|
471
479
|
</li>
|
|
472
480
|
|
|
473
481
|
|
|
474
|
-
<li class="
|
|
482
|
+
<li class="odd ">
|
|
475
483
|
<div class="item">
|
|
476
484
|
<span class='object_link'><a href="Mint/Money.html#same_currency%3F-instance_method" title="Mint::Money#same_currency? (method)">#same_currency?</a></span>
|
|
477
485
|
<small>Mint::Money</small>
|
|
@@ -479,7 +487,7 @@
|
|
|
479
487
|
</li>
|
|
480
488
|
|
|
481
489
|
|
|
482
|
-
<li class="
|
|
490
|
+
<li class="even ">
|
|
483
491
|
<div class="item">
|
|
484
492
|
<span class='object_link'><a href="Mint/Money.html#split-instance_method" title="Mint::Money#split (method)">#split</a></span>
|
|
485
493
|
<small>Mint::Money</small>
|
|
@@ -487,7 +495,7 @@
|
|
|
487
495
|
</li>
|
|
488
496
|
|
|
489
497
|
|
|
490
|
-
<li class="
|
|
498
|
+
<li class="odd ">
|
|
491
499
|
<div class="item">
|
|
492
500
|
<span class='object_link'><a href="Mint/RangeStepPatch.html#step-instance_method" title="Mint::RangeStepPatch#step (method)">#step</a></span>
|
|
493
501
|
<small>Mint::RangeStepPatch</small>
|
|
@@ -495,7 +503,7 @@
|
|
|
495
503
|
</li>
|
|
496
504
|
|
|
497
505
|
|
|
498
|
-
<li class="
|
|
506
|
+
<li class="even ">
|
|
499
507
|
<div class="item">
|
|
500
508
|
<span class='object_link'><a href="Mint/Currency.html#subunit-instance_method" title="Mint::Currency#subunit (method)">#subunit</a></span>
|
|
501
509
|
<small>Mint::Currency</small>
|
|
@@ -503,6 +511,14 @@
|
|
|
503
511
|
</li>
|
|
504
512
|
|
|
505
513
|
|
|
514
|
+
<li class="odd ">
|
|
515
|
+
<div class="item">
|
|
516
|
+
<span class='object_link'><a href="Mint/Money.html#subunits-instance_method" title="Mint::Money#subunits (method)">#subunits</a></span>
|
|
517
|
+
<small>Mint::Money</small>
|
|
518
|
+
</div>
|
|
519
|
+
</li>
|
|
520
|
+
|
|
521
|
+
|
|
506
522
|
<li class="even ">
|
|
507
523
|
<div class="item">
|
|
508
524
|
<span class='object_link'><a href="Mint/Money.html#succ-instance_method" title="Mint::Money#succ (method)">#succ</a></span>
|
|
@@ -609,31 +625,31 @@
|
|
|
609
625
|
|
|
610
626
|
<li class="odd ">
|
|
611
627
|
<div class="item">
|
|
612
|
-
<span class='object_link'><a href="Mint.html#world_currencies-class_method" title="Mint.world_currencies (method)">world_currencies</a></span>
|
|
613
|
-
<small>Mint</small>
|
|
628
|
+
<span class='object_link'><a href="Mint/Registry.html#world_currencies-class_method" title="Mint::Registry.world_currencies (method)">world_currencies</a></span>
|
|
629
|
+
<small>Mint::Registry</small>
|
|
614
630
|
</div>
|
|
615
631
|
</li>
|
|
616
632
|
|
|
617
633
|
|
|
618
634
|
<li class="even ">
|
|
619
635
|
<div class="item">
|
|
620
|
-
<span class='object_link'><a href="Mint
|
|
621
|
-
<small>Mint
|
|
636
|
+
<span class='object_link'><a href="Mint.html#world_currencies-class_method" title="Mint.world_currencies (method)">world_currencies</a></span>
|
|
637
|
+
<small>Mint</small>
|
|
622
638
|
</div>
|
|
623
639
|
</li>
|
|
624
640
|
|
|
625
641
|
|
|
626
642
|
<li class="odd ">
|
|
627
643
|
<div class="item">
|
|
628
|
-
<span class='object_link'><a href="Mint/
|
|
629
|
-
<small>Mint::
|
|
644
|
+
<span class='object_link'><a href="Mint/Currency.html#zero-class_method" title="Mint::Currency.zero (method)">zero</a></span>
|
|
645
|
+
<small>Mint::Currency</small>
|
|
630
646
|
</div>
|
|
631
647
|
</li>
|
|
632
648
|
|
|
633
649
|
|
|
634
650
|
<li class="even ">
|
|
635
651
|
<div class="item">
|
|
636
|
-
<span class='object_link'><a href="Mint/Currency.html#zero-
|
|
652
|
+
<span class='object_link'><a href="Mint/Currency.html#zero-instance_method" title="Mint::Currency#zero (method)">#zero</a></span>
|
|
637
653
|
<small>Mint::Currency</small>
|
|
638
654
|
</div>
|
|
639
655
|
</li>
|
|
@@ -641,8 +657,8 @@
|
|
|
641
657
|
|
|
642
658
|
<li class="odd ">
|
|
643
659
|
<div class="item">
|
|
644
|
-
<span class='object_link'><a href="Mint/
|
|
645
|
-
<small>Mint::
|
|
660
|
+
<span class='object_link'><a href="Mint/Money.html#zero-class_method" title="Mint::Money.zero (method)">zero</a></span>
|
|
661
|
+
<small>Mint::Money</small>
|
|
646
662
|
</div>
|
|
647
663
|
</li>
|
|
648
664
|
|
|
@@ -141,7 +141,7 @@
|
|
|
141
141
|
</div>
|
|
142
142
|
|
|
143
143
|
<div id="footer">
|
|
144
|
-
Generated on
|
|
144
|
+
Generated on Mon Jun 22 16:47:02 2026 by
|
|
145
145
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
146
146
|
0.9.44 (ruby-4.0.5).
|
|
147
147
|
</div>
|
|
@@ -40,8 +40,13 @@ module Mint
|
|
|
40
40
|
# Normalizes numeric amounts for this currency
|
|
41
41
|
# 1. Converts to Rational
|
|
42
42
|
# 2. Rounds to respect currency subunit
|
|
43
|
-
def normalize_amount(amount) =
|
|
43
|
+
def normalize_amount(amount) = amount.to_r.round(subunit)
|
|
44
44
|
|
|
45
|
+
# Returns the cached frozen zero-Money for this currency.
|
|
46
|
+
#
|
|
47
|
+
# @return [Money] a frozen zero-Money instance
|
|
48
|
+
# @example
|
|
49
|
+
# Mint::Currency.for_code('USD').zero #=> [USD 0.00]
|
|
45
50
|
def zero = Registry.zero_for(self)
|
|
46
51
|
end
|
|
47
52
|
|
|
@@ -26,4 +26,31 @@ module Mint
|
|
|
26
26
|
# @return [Proc, #call, nil]
|
|
27
27
|
attr_accessor :locale_backend
|
|
28
28
|
end
|
|
29
|
+
|
|
30
|
+
# @api private
|
|
31
|
+
class Money
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
# Resolves format/decimal/thousand from locale_backend when not explicitly given.
|
|
35
|
+
# @private
|
|
36
|
+
def resolve_locale_for(format, decimal, thousand)
|
|
37
|
+
locale = locale_backend
|
|
38
|
+
|
|
39
|
+
[format || locale[:format] || '%<symbol>s%<amount>f',
|
|
40
|
+
decimal || locale[:decimal] || '.',
|
|
41
|
+
thousand.nil? ? (locale[:thousand] || ',') : thousand]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def locale_backend
|
|
45
|
+
case bk = Mint.locale_backend
|
|
46
|
+
when Hash then bk
|
|
47
|
+
when NilClass then {}
|
|
48
|
+
else
|
|
49
|
+
return bk.call if bk.respond_to?(:call)
|
|
50
|
+
|
|
51
|
+
warn "ignoring invalid locale_backend: #{bk.inspect}"
|
|
52
|
+
{}
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
29
56
|
end
|
data/lib/minting/mint/mint.rb
CHANGED
|
@@ -24,9 +24,18 @@ module Mint
|
|
|
24
24
|
# Restores the previous mode (or default) when the block exits, even on
|
|
25
25
|
# exception.
|
|
26
26
|
#
|
|
27
|
+
# Rounding-mode support is loaded lazily on first call. Once loaded,
|
|
28
|
+
# +Currency#normalize_amount+ is patched to dispatch through the
|
|
29
|
+
# rounding module, adding ~10–35&ns of overhead to every money creation
|
|
30
|
+
# or mutation. When rounding modes are never used (the common case),
|
|
31
|
+
# the fast path incurs zero overhead.
|
|
32
|
+
#
|
|
27
33
|
# @param mode [Symbol] one of: +:half_up+, +:half_down+, +:floor+,
|
|
28
34
|
# +:ceil+, +:truncate+, +:down+
|
|
29
35
|
# @yield block to execute with the rounding mode active
|
|
30
36
|
# @raise [ArgumentError] if +mode+ is not a recognised rounding mode
|
|
31
|
-
def self.with_rounding(mode, &)
|
|
37
|
+
def self.with_rounding(mode, &)
|
|
38
|
+
require_relative 'rounding' unless defined?(Mint::Rounding)
|
|
39
|
+
Rounding.with_mode(mode, &)
|
|
40
|
+
end
|
|
32
41
|
end
|
|
@@ -11,6 +11,8 @@ module Mint
|
|
|
11
11
|
def self.zero_for(currency)
|
|
12
12
|
raise ArgumentError, "Expect a Currency param. (#{currency})" unless currency.is_a?(Currency)
|
|
13
13
|
|
|
14
|
+
return @zeros[currency] if @zeros&.key?(currency)
|
|
15
|
+
|
|
14
16
|
MUTEX.synchronize do
|
|
15
17
|
@zeros ||= {}
|
|
16
18
|
@zeros[currency] ||= Mint::Money.send(:new, 0r, currency)
|
|
@@ -24,12 +24,18 @@ module Mint
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
# Rounds +amount+ to +ndigits+ using the currently scoped rounding mode.
|
|
27
|
+
# Uses the fast path (+to_r.round+) when no custom mode is active.
|
|
27
28
|
# @api private
|
|
28
29
|
# @param amount [Numeric]
|
|
29
30
|
# @param ndigits [Integer]
|
|
30
31
|
# @return [Rational]
|
|
31
32
|
def self.apply(amount, ndigits)
|
|
32
|
-
|
|
33
|
+
mode = Thread.current[:minting_rounding_mode]
|
|
34
|
+
if mode
|
|
35
|
+
MODES.fetch(mode).call(amount.to_r, ndigits)
|
|
36
|
+
else
|
|
37
|
+
amount.to_r.round(ndigits)
|
|
38
|
+
end
|
|
33
39
|
end
|
|
34
40
|
|
|
35
41
|
# Sets a rounding mode for the duration of a block, restoring the
|
|
@@ -49,3 +55,10 @@ module Mint
|
|
|
49
55
|
end
|
|
50
56
|
end
|
|
51
57
|
end
|
|
58
|
+
|
|
59
|
+
# When loaded, patch Currency to delegate rounding through this module.
|
|
60
|
+
# Remove the default fast-path method first to avoid redefinition warnings.
|
|
61
|
+
Mint::Currency.remove_method(:normalize_amount)
|
|
62
|
+
Mint::Currency.define_method(:normalize_amount) do |amount|
|
|
63
|
+
Mint::Rounding.apply(amount, subunit)
|
|
64
|
+
end
|
data/lib/minting/mint.rb
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative 'mint/rounding'
|
|
4
3
|
require_relative 'currency/currency'
|
|
5
4
|
|
|
6
5
|
require_relative 'mint/dsl/numeric'
|
|
7
6
|
require_relative 'mint/dsl/range'
|
|
8
7
|
require_relative 'mint/dsl/string'
|
|
9
8
|
require_relative 'mint/dsl/top_level'
|
|
10
|
-
require_relative 'mint/
|
|
9
|
+
require_relative 'mint/i18n'
|
|
11
10
|
require_relative 'mint/mint'
|
|
12
11
|
require_relative 'mint/parser/parser'
|
|
13
12
|
require_relative 'mint/parser/separators'
|
data/lib/minting/money/clamp.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Mint
|
|
4
|
-
#
|
|
4
|
+
# :nodoc:
|
|
5
5
|
class Money
|
|
6
6
|
# Constrains +self+ to the inclusive range [+min+, +max+].
|
|
7
7
|
#
|
|
@@ -58,7 +58,7 @@ module Mint
|
|
|
58
58
|
case boundary
|
|
59
59
|
in NilClass | Numeric then boundary
|
|
60
60
|
in Money if same_currency?(boundary) then boundary.amount
|
|
61
|
-
in Money then raise ArgumentError, "
|
|
61
|
+
in Money then raise ArgumentError, "Boundary currency must be: #{currency_code}"
|
|
62
62
|
else raise ArgumentError, "Boundary must be Numeric or Money #{boundary}"
|
|
63
63
|
end
|
|
64
64
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Mint
|
|
4
|
-
#
|
|
4
|
+
# :nodoc:
|
|
5
5
|
class Money
|
|
6
6
|
# Allows {Money} to interact seamlessly as the right-hand operand in Numeric arithmetic.
|
|
7
7
|
# This enables expressions like `5 * money` where `5` is a Numeric and `money` is a Money object.
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Mint
|
|
4
|
-
#
|
|
4
|
+
# :nodoc:
|
|
5
5
|
class Money
|
|
6
6
|
# Creates a new Money immutable object with the specified amount and currency
|
|
7
7
|
# @param amount [Numeric] The monetary amount
|
|
8
8
|
# @param currency [Currency, String] The currency code or currency object
|
|
9
|
+
# @return [Money] the new Money instance
|
|
9
10
|
# @raise [ArgumentError] If amount is not numeric or currency is invalid
|
|
11
|
+
# @example
|
|
12
|
+
# Money.from(10, 'USD') #=> [USD 10.00]
|
|
10
13
|
def self.from(amount, currency)
|
|
11
14
|
raise ArgumentError, 'amount must be Numeric' unless amount.is_a?(Numeric)
|
|
12
15
|
|
|
@@ -68,29 +71,29 @@ module Mint
|
|
|
68
71
|
from(amount, currency)
|
|
69
72
|
end
|
|
70
73
|
|
|
71
|
-
# Builds a Money from a
|
|
72
|
-
# This is the inverse of {#
|
|
74
|
+
# Builds a Money from a subunit (smallest-unit) Integer amount.
|
|
75
|
+
# This is the inverse of {#subunits}: for USD, the subunit is
|
|
73
76
|
# 1 cent; for JPY it is 1 yen; for IQD it is 1 dinar (subunit 3).
|
|
74
77
|
#
|
|
75
|
-
# @param
|
|
78
|
+
# @param subunits [Integer] the amount expressed in the currency's
|
|
76
79
|
# smallest unit (e.g. cents). Must be an Integer to preserve exactness.
|
|
77
80
|
# @param currency [String, Symbol, Currency] the currency identifier
|
|
78
81
|
# @return [Money] the resulting Money instance
|
|
79
|
-
# @raise [ArgumentError] if +
|
|
82
|
+
# @raise [ArgumentError] if +subunits+ is not an Integer or +currency+
|
|
80
83
|
# is not registered
|
|
81
84
|
#
|
|
82
85
|
# @example USD cents
|
|
83
|
-
# Money.
|
|
86
|
+
# Money.from_subunits(123_456, 'USD') #=> [USD 1234.56]
|
|
84
87
|
# @example JPY (subunit 0)
|
|
85
|
-
# Money.
|
|
88
|
+
# Money.from_subunits(1234, 'JPY') #=> [JPY 1234]
|
|
86
89
|
# @example Round trip
|
|
87
90
|
# m = Mint.money(9.99, 'USD')
|
|
88
|
-
# Money.
|
|
89
|
-
def self.
|
|
90
|
-
raise ArgumentError, '
|
|
91
|
+
# Money.from_subunits(m.subunits, 'USD') == m #=> true
|
|
92
|
+
def self.from_subunits(subunits, currency)
|
|
93
|
+
raise ArgumentError, 'subunits must be an Integer' unless subunits.is_a?(Integer)
|
|
91
94
|
|
|
92
95
|
currency = Currency.resolve!(currency)
|
|
93
|
-
amount = Rational(
|
|
96
|
+
amount = Rational(subunits, currency.fractional_multiplier)
|
|
94
97
|
amount.zero? ? currency.zero : new(amount, currency)
|
|
95
98
|
end
|
|
96
99
|
|
|
@@ -116,6 +119,13 @@ module Mint
|
|
|
116
119
|
end
|
|
117
120
|
end
|
|
118
121
|
|
|
122
|
+
# Returns a new Money with the given amount in the same currency.
|
|
123
|
+
#
|
|
124
|
+
# @deprecated Use {#copy_with} instead. Will be removed in v2.
|
|
125
|
+
# @param new_amount [Numeric] the new monetary amount
|
|
126
|
+
# @return [Money] a new Money instance, or self if unchanged
|
|
127
|
+
# @example
|
|
128
|
+
# Mint.money(10, 'USD').mint(15) #=> [USD 15.00]
|
|
119
129
|
def mint(new_amount)
|
|
120
130
|
warn 'Money#mint is now deprecated and will be removed in v2'
|
|
121
131
|
copy_with(amount: new_amount)
|