money 6.13.4 → 6.14.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,7 +16,7 @@ class Money
16
16
  # @example
17
17
  # - Money.new(100) #=> #<Money @fractional=-100>
18
18
  def -@
19
- self.class.new(-fractional, currency, bank)
19
+ dup_with(fractional: -fractional)
20
20
  end
21
21
 
22
22
  # Checks whether two Money objects have the same currency and the same
@@ -46,7 +46,7 @@ class Money
46
46
  # Compares two Money objects. If money objects have a different currency it
47
47
  # will attempt to convert the currency.
48
48
  #
49
- # @param [Money] other_money Value to compare with.
49
+ # @param [Money] other Value to compare with.
50
50
  #
51
51
  # @return [Integer]
52
52
  #
@@ -57,7 +57,12 @@ class Money
57
57
  return unless other.respond_to?(:zero?) && other.zero?
58
58
  return other.is_a?(CoercedNumeric) ? 0 <=> fractional : fractional <=> 0
59
59
  end
60
- return 0 if zero? && other.zero?
60
+
61
+ # Always allow comparison with zero
62
+ if zero? || other.zero?
63
+ return fractional <=> other.fractional
64
+ end
65
+
61
66
  other = other.exchange_to(currency)
62
67
  fractional <=> other.fractional
63
68
  rescue Money::Bank::UnknownRate
@@ -103,7 +108,7 @@ class Money
103
108
  # values. If +other_money+ has a different currency then its monetary value
104
109
  # is automatically exchanged to this object's currency using +exchange_to+.
105
110
  #
106
- # @param [Money] other_money Other +Money+ object to add.
111
+ # @param [Money] other Other +Money+ object to add.
107
112
  #
108
113
  # @return [Money]
109
114
  #
@@ -116,7 +121,7 @@ class Money
116
121
  # its monetary value is automatically exchanged to this object's currency
117
122
  # using +exchange_to+.
118
123
  #
119
- # @param [Money] other_money Other +Money+ object to subtract.
124
+ # @param [Money] other Other +Money+ object to subtract.
120
125
  #
121
126
  # @return [Money]
122
127
  #
@@ -132,10 +137,10 @@ class Money
132
137
  when Money
133
138
  other = other.exchange_to(currency)
134
139
  new_fractional = fractional.public_send(op, other.fractional)
135
- self.class.new(new_fractional, currency, bank)
140
+ dup_with(fractional: new_fractional)
136
141
  when CoercedNumeric
137
142
  raise TypeError, non_zero_message.call(other.value) unless other.zero?
138
- self.class.new(other.value.public_send(op, fractional), currency)
143
+ dup_with(fractional: other.value.public_send(op, fractional))
139
144
  when Numeric
140
145
  raise TypeError, non_zero_message.call(other) unless other.zero?
141
146
  self
@@ -162,7 +167,7 @@ class Money
162
167
  def *(value)
163
168
  value = value.value if value.is_a?(CoercedNumeric)
164
169
  if value.is_a? Numeric
165
- self.class.new(fractional * value, currency, bank)
170
+ dup_with(fractional: fractional * value)
166
171
  else
167
172
  raise TypeError, "Can't multiply a #{self.class.name} by a #{value.class.name}'s value"
168
173
  end
@@ -188,7 +193,7 @@ class Money
188
193
  fractional / as_d(value.exchange_to(currency).fractional).to_f
189
194
  else
190
195
  raise TypeError, 'Can not divide by Money' if value.is_a?(CoercedNumeric)
191
- self.class.new(fractional / as_d(value), currency, bank)
196
+ dup_with(fractional: fractional / as_d(value))
192
197
  end
193
198
  end
194
199
 
@@ -226,13 +231,13 @@ class Money
226
231
  def divmod_money(val)
227
232
  cents = val.exchange_to(currency).cents
228
233
  quotient, remainder = fractional.divmod(cents)
229
- [quotient, self.class.new(remainder, currency, bank)]
234
+ [quotient, dup_with(fractional: remainder)]
230
235
  end
231
236
  private :divmod_money
232
237
 
233
238
  def divmod_other(val)
234
239
  quotient, remainder = fractional.divmod(as_d(val))
235
- [self.class.new(quotient, currency, bank), self.class.new(remainder, currency, bank)]
240
+ [dup_with(fractional: quotient), dup_with(fractional: remainder)]
236
241
  end
237
242
  private :divmod_other
238
243
 
@@ -276,7 +281,7 @@ class Money
276
281
  if (fractional < 0 && val < 0) || (fractional > 0 && val > 0)
277
282
  self.modulo(val)
278
283
  else
279
- self.modulo(val) - (val.is_a?(Money) ? val : self.class.new(val, currency, bank))
284
+ self.modulo(val) - (val.is_a?(Money) ? val : dup_with(fractional: val))
280
285
  end
281
286
  end
282
287
 
@@ -287,7 +292,7 @@ class Money
287
292
  # @example
288
293
  # Money.new(-100).abs #=> #<Money @fractional=100>
289
294
  def abs
290
- self.class.new(fractional.abs, currency, bank)
295
+ dup_with(fractional: fractional.abs)
291
296
  end
292
297
 
293
298
  # Test if the money amount is zero.
@@ -79,6 +79,8 @@ class Money
79
79
  end
80
80
 
81
81
  def determine_format_from_formatting_rules(rules)
82
+ return currency.format if currency.format && !rules.has_key?(:symbol_position)
83
+
82
84
  symbol_position = symbol_position_from(rules)
83
85
 
84
86
  if symbol_position == :before
@@ -1,3 +1,5 @@
1
+ require 'monitor'
2
+
1
3
  class Money
2
4
  module RatesStore
3
5
 
@@ -17,11 +19,11 @@ class Money
17
19
  #
18
20
  # @param [Hash] opts Optional store options.
19
21
  # @option opts [Boolean] :without_mutex disables the usage of a mutex
20
- # @param [Hash] rt Optional initial exchange rate data.
21
- def initialize(opts = {}, rt = {})
22
- @options, @index = opts, rt
23
- @mutex = Mutex.new
24
- @in_transaction = false
22
+ # @param [Hash] rates Optional initial exchange rate data.
23
+ def initialize(opts = {}, rates = {})
24
+ @rates = rates
25
+ @options = opts
26
+ @guard = Monitor.new
25
27
  end
26
28
 
27
29
  # Registers a conversion rate and returns it. Uses +Mutex+ to synchronize data access.
@@ -37,7 +39,9 @@ class Money
37
39
  # store.add_rate("USD", "CAD", 1.24515)
38
40
  # store.add_rate("CAD", "USD", 0.803115)
39
41
  def add_rate(currency_iso_from, currency_iso_to, rate)
40
- transaction { index[rate_key_for(currency_iso_from, currency_iso_to)] = rate }
42
+ guard.synchronize do
43
+ rates[rate_key_for(currency_iso_from, currency_iso_to)] = rate
44
+ end
41
45
  end
42
46
 
43
47
  # Retrieve the rate for the given currencies. Uses +Mutex+ to synchronize data access.
@@ -54,24 +58,21 @@ class Money
54
58
  #
55
59
  # store.get_rate("USD", "CAD") #=> 1.24515
56
60
  def get_rate(currency_iso_from, currency_iso_to)
57
- transaction { index[rate_key_for(currency_iso_from, currency_iso_to)] }
61
+ guard.synchronize do
62
+ rates[rate_key_for(currency_iso_from, currency_iso_to)]
63
+ end
58
64
  end
59
65
 
60
66
  def marshal_dump
61
- [self.class, options, index]
67
+ guard.synchronize do
68
+ return [self.class, options, rates.dup]
69
+ end
62
70
  end
63
71
 
64
72
  # Wraps block execution in a thread-safe transaction
65
73
  def transaction(&block)
66
- if @in_transaction || options[:without_mutex]
67
- block.call self
68
- else
69
- @mutex.synchronize do
70
- @in_transaction = true
71
- result = block.call
72
- @in_transaction = false
73
- result
74
- end
74
+ guard.synchronize do
75
+ yield
75
76
  end
76
77
  end
77
78
 
@@ -88,19 +89,19 @@ class Money
88
89
  # puts [iso_from, iso_to, rate].join
89
90
  # end
90
91
  def each_rate(&block)
91
- enum = Enumerator.new do |yielder|
92
- index.each do |key, rate|
92
+ return to_enum(:each_rate) unless block_given?
93
+
94
+ guard.synchronize do
95
+ rates.each do |key, rate|
93
96
  iso_from, iso_to = key.split(INDEX_KEY_SEPARATOR)
94
- yielder.yield iso_from, iso_to, rate
97
+ yield iso_from, iso_to, rate
95
98
  end
96
99
  end
97
-
98
- block_given? ? enum.each(&block) : enum
99
100
  end
100
101
 
101
102
  private
102
103
 
103
- attr_reader :index, :options
104
+ attr_reader :rates, :options, :guard
104
105
 
105
106
  # Return the rate hashkey for the given currencies.
106
107
  #
@@ -1,3 +1,3 @@
1
1
  class Money
2
- VERSION = '6.13.4'
2
+ VERSION = '6.14.0'
3
3
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: money
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.13.4
4
+ version: 6.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shane Emmons
8
8
  - Anthony Dmitriyev
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-06-10 00:00:00.000000000 Z
12
+ date: 2021-01-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: i18n
@@ -144,7 +144,7 @@ metadata:
144
144
  changelog_uri: https://github.com/RubyMoney/money/blob/master/CHANGELOG.md
145
145
  source_code_uri: https://github.com/RubyMoney/money/
146
146
  bug_tracker_uri: https://github.com/RubyMoney/money/issues
147
- post_install_message:
147
+ post_install_message:
148
148
  rdoc_options: []
149
149
  require_paths:
150
150
  - lib
@@ -159,9 +159,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
159
  - !ruby/object:Gem::Version
160
160
  version: '0'
161
161
  requirements: []
162
- rubyforge_project:
163
- rubygems_version: 2.6.8
164
- signing_key:
162
+ rubygems_version: 3.0.3
163
+ signing_key:
165
164
  specification_version: 4
166
165
  summary: A Ruby Library for dealing with money and currency conversion.
167
166
  test_files: []