money 3.1.5 → 3.5.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.
@@ -1,3 +1,27 @@
1
+ Money 3.5.0
2
+ ===========
3
+
4
+ Features
5
+ --------
6
+ - Updated to RSpec2.
7
+ - Use i18n to lookup separator and delimiter signs.
8
+ - Removed all deprecated methods up to v3.5.0, including the following:
9
+ - Using Money#format with params instead of a Hash.
10
+ - Using a Hash with Money#new.
11
+ - Using Bank#exchange, use Bank#exchange_with instead.
12
+
13
+ Bugfixes
14
+ --------
15
+ - Updated Money#to_s to respect :separator and :subunit_to_unit.
16
+ - Fixed Money#format for :subunit_to_unit != 100.
17
+ ([#issue/37](http://github.com/RubyMoney/money/issue/37))
18
+ - Fixed String#to_money for :subunit_to_unit != 100.
19
+ ([#issue/36](http://github.com/RubyMoney/money/issue/36))
20
+ - Removed duplicate currencies.
21
+ ([#issue/38](http://github.com/RubyMoney/money/issue/38))
22
+ - Fixed issue related to JRuby returning 2 for Math.log10(1000).floor instead
23
+ of correctly returning 3.
24
+
1
25
  Money 3.1.5
2
26
  ===========
3
27
 
data/README.md CHANGED
@@ -177,15 +177,6 @@ There is nothing stopping you from creating bank objects which scrapes
177
177
 
178
178
  Money.default_bank = ExchangeBankWhichScrapesXeDotCom.new
179
179
 
180
- ### Upcoming Changes
181
-
182
- Starting in v3.1.0 we will be making two changes to the exchange process. First
183
- a new `Bank::Base` class will be available. This will allow users to more
184
- easily create custom `Bank` classes. Secondly the default `#exchange` method
185
- will be depreciated and a new `#exchange_with` method will be used. Currently
186
- `#exchange` passes the `cents` attribute. `#exchange_with` will pass the
187
- actual `Money` object instead.
188
-
189
180
  ### Implementations
190
181
 
191
182
  The following is a list of Money.gem compatible currency exchange rate
@@ -21,8 +21,8 @@
21
21
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
 
23
23
  require 'bigdecimal'
24
+ require 'i18n' rescue LoadError
24
25
  require 'money/currency'
25
26
  require 'money/money'
26
27
  require 'money/defaults'
27
28
  require 'money/core_extensions'
28
- require 'money/deprecations'
@@ -84,13 +84,6 @@ class Money
84
84
  def setup
85
85
  end
86
86
 
87
- # @deprecated +#exchange+ will be removed in v3.2.0, use +#exchange_with+
88
- # @see Money::Bank::Base#exchange_with
89
- def exchange(cents, from_currency, to_currency, &block)
90
- Money.deprecate "`Money::Bank::Base#exchange' will be removed in v3.2.0, use #exchange_with instead"
91
- exchange_with(Money.new(cents, from_currency), to_currency, &block).cents
92
- end
93
-
94
87
  # Exchanges the given +Money+ object to a new +Money+ object in
95
88
  # +to_currency+.
96
89
  #
@@ -51,7 +51,6 @@ class Money
51
51
  :cad => { :priority => 5, :iso_code => "CAD", :name => "Canadian Dollar", :symbol => "$", :subunit => "Cent", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
52
52
  :cdf => { :priority => 100, :iso_code => "CDF", :name => "Congolese Franc", :symbol => "Fr", :subunit => "Centime", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
53
53
  :chf => { :priority => 100, :iso_code => "CHF", :name => "Swiss Franc", :symbol => "Fr", :subunit => "Rappen", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
54
- :chf => { :priority => 100, :iso_code => "CHF", :name => "Swiss Franc", :symbol => "Fr", :subunit => "Rappen", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
55
54
  :clp => { :priority => 100, :iso_code => "CLP", :name => "Chilean Peso", :symbol => "$", :subunit => "Peso", :subunit_to_unit => 1, :separator => ",", :delimiter => "." },
56
55
  :cny => { :priority => 100, :iso_code => "CNY", :name => "Chinese Renminbi Yuan", :symbol => "¥", :subunit => "Jiao", :subunit_to_unit => 10, :separator => ".", :delimiter => "," },
57
56
  :cop => { :priority => 100, :iso_code => "COP", :name => "Colombian Peso", :symbol => "$", :subunit => "Centavo", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
@@ -142,7 +141,6 @@ class Money
142
141
  :ron => { :priority => 100, :iso_code => "RON", :name => "Romanian Leu", :symbol => "L", :subunit => "Ban", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
143
142
  :rsd => { :priority => 100, :iso_code => "RSD", :name => "Serbian Dinar", :symbol => "din. or дин.", :subunit => "Para", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
144
143
  :rub => { :priority => 100, :iso_code => "RUB", :name => "Russian Ruble", :symbol => "р.", :subunit => "Kopek", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
145
- :rub => { :priority => 100, :iso_code => "RUB", :name => "Russian Ruble", :symbol => "руб.", :subunit => "Kopek", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
146
144
  :rwf => { :priority => 100, :iso_code => "RWF", :name => "Rwandan Franc", :symbol => "Fr", :subunit => "Centime", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
147
145
  :sar => { :priority => 100, :iso_code => "SAR", :name => "Saudi Riyal", :symbol => "ر.س", :subunit => "Hallallah", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
148
146
  :sbd => { :priority => 100, :iso_code => "SBD", :name => "Solomon Islands Dollar", :symbol => "$", :subunit => "Cent", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
@@ -165,7 +163,6 @@ class Money
165
163
  :tnd => { :priority => 100, :iso_code => "TND", :name => "Tunisian Dinar", :symbol => "د.ت", :subunit => "Millime", :subunit_to_unit => 1000, :separator => ".", :delimiter => "," },
166
164
  :top => { :priority => 100, :iso_code => "TOP", :name => "Tongan Paʻanga", :symbol => "T$", :subunit => "Seniti", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
167
165
  :try => { :priority => 100, :iso_code => "TRY", :name => "Turkish New Lira", :symbol => "YTL", :subunit => "New kuruş", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
168
- :try => { :priority => 100, :iso_code => "TRY", :name => "Turkish New Lira", :symbol => "₤", :subunit => "New kuruş", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
169
166
  :ttd => { :priority => 100, :iso_code => "TTD", :name => "Trinidad and Tobago Dollar", :symbol => "$", :subunit => "Cent", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
170
167
  :twd => { :priority => 100, :iso_code => "TWD", :name => "New Taiwan Dollar", :symbol => "$", :subunit => "Cent", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
171
168
  :tzs => { :priority => 100, :iso_code => "TZS", :name => "Tanzanian Shilling", :symbol => "Sh", :subunit => "Cent", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
@@ -343,12 +340,6 @@ class Money
343
340
  "#<#{self.class.name} id: #{id} #{ATTRIBUTES.map { |a| "#{a}: #{send(a)}" }.join(", ")}>"
344
341
  end
345
342
 
346
- # Catches deprecated uses of currency.
347
- def method_missing(method, *args, &block)
348
- Money.deprecate "`currency` is now a `Currency` instance. Call `currency.to_s.#{method}' instead."
349
- iso_code.send(method, *args, &block)
350
- end
351
-
352
343
  # Class Methods
353
344
  class << self
354
345
 
@@ -387,19 +387,7 @@ class Money
387
387
  #
388
388
  def initialize(cents, currency = Money.default_currency, bank = Money.default_bank)
389
389
  @cents = cents.round
390
- if currency.is_a?(Hash)
391
- # Earlier versions of Money wrongly documented the constructor as being able
392
- # to accept something like this:
393
- #
394
- # Money.new(50, :currency => "USD")
395
- #
396
- # We retain compatibility here.
397
- Money.deprecate "Passing :currency as option is deprecated and will be removed in v3.5.0. " +
398
- "Please use `Money.new('#{cents}'#{currency[:currency].nil? ? "" : ", '#{currency[:currency]}'"})'"
399
- @currency = Currency.wrap(currency[:currency] || Money.default_currency)
400
- else
401
- @currency = Currency.wrap(currency)
402
- end
390
+ @currency = Currency.wrap(currency)
403
391
  @bank = bank
404
392
  end
405
393
 
@@ -724,24 +712,40 @@ class Money
724
712
  currency.symbol || "¤"
725
713
  end
726
714
 
727
- # Uses +Currency#delimiter+. If +nil+ is returned, default to ",".
715
+ # If I18n is loaded, looks up key +:number.format.delimiter+.
716
+ # Otherwise and as fallback it uses +Currency#delimiter+.
717
+ # If +nil+ is returned, default to ",".
728
718
  #
729
719
  # @return [String]
730
720
  #
731
721
  # @example
732
722
  # Money.new(100, "USD").delimiter #=> ","
733
- def delimiter
734
- currency.delimiter || ","
723
+ if Object.const_defined?("I18n")
724
+ def delimiter
725
+ I18n.t(:"number.format.delimiter", :default => currency.delimiter || ",")
726
+ end
727
+ else
728
+ def delimiter
729
+ currency.delimiter || ","
730
+ end
735
731
  end
736
732
 
737
- # Uses +Currency#separator+. If +nil+ is returned, default to ".".
733
+ # If I18n is loaded, looks up key +:number.format.seperator+.
734
+ # Otherwise and as fallback it uses +Currency#seperator+.
735
+ # If +nil+ is returned, default to ",".
738
736
  #
739
737
  # @return [String]
740
738
  #
741
739
  # @example
742
740
  # Money.new(100, "USD").separator #=> "."
743
- def separator
744
- currency.separator || "."
741
+ if Object.const_defined?("I18n")
742
+ def separator
743
+ I18n.t(:"number.format.separator", :default => currency.separator || ".")
744
+ end
745
+ else
746
+ def separator
747
+ currency.separator || "."
748
+ end
745
749
  end
746
750
 
747
751
  # Creates a formatted price string according to several rules.
@@ -856,10 +860,15 @@ class Money
856
860
  symbol_value = symbol
857
861
  end
858
862
 
859
- if rules[:no_cents] or currency.subunit_to_unit == 1
860
- formatted = sprintf("#{symbol_value}%d", self.to_f)
861
- else
862
- formatted = sprintf("#{symbol_value}%.2f", self.to_f)
863
+ formatted = case rules[:no_cents]
864
+ when true
865
+ "#{symbol_value}#{self.to_s.to_i}"
866
+ else
867
+ "#{symbol_value}#{self.to_s}"
868
+ end
869
+ if rules.has_key?(:separator) and rules[:separator] and
870
+ rules[:separator] != separator
871
+ formatted.sub!(separator, rules[:separator])
863
872
  end
864
873
 
865
874
  delimiter_value = delimiter
@@ -873,16 +882,7 @@ class Money
873
882
  end
874
883
 
875
884
  # Apply delimiter
876
- formatted.gsub!(/(\d)(?=(?:\d{3})+(?:\.|$))(\d{3}\..*)?/, "\\1#{delimiter_value}\\2")
877
-
878
- separator_value = separator
879
- # Determine separator
880
- if rules.has_key?(:separator) and rules[:separator]
881
- separator_value = rules[:separator]
882
- end
883
-
884
- # Apply separator
885
- formatted.sub!(/\.(\d{2})$/, "#{separator_value}\\1")
885
+ formatted.gsub!(/(\d)(?=(?:\d{3})+(?:\.|,|$))(\d{3}\..*)?/, "\\1#{delimiter_value}\\2")
886
886
 
887
887
  if rules[:with_currency]
888
888
  formatted << " "
@@ -900,8 +900,11 @@ class Money
900
900
  # @example
901
901
  # Money.ca_dollar(100).to_s #=> "1.00"
902
902
  def to_s
903
- return sprintf("%d", cents) if currency.subunit_to_unit == 1
904
- sprintf("%.2f", self.to_f)
903
+ decimal_places = Math.log10(currency.subunit_to_unit).ceil
904
+ unit, subunit = cents.divmod(currency.subunit_to_unit).map{|o| o.to_s}
905
+ return unit if decimal_places == 0
906
+ subunit = (subunit + ("0" * decimal_places))[0, decimal_places]
907
+ "#{unit}#{separator}#{subunit}"
905
908
  end
906
909
 
907
910
  # Return the amount of money as a float. Floating points cannot guarantee
@@ -987,13 +990,6 @@ class Money
987
990
  elsif rules.size == 1
988
991
  rules = rules.pop
989
992
  rules = { rules => true } if rules.is_a?(Symbol)
990
- else
991
- Money.deprecate "Passing options as parameters is deprecated and will be removed in v3.5.0. " +
992
- "Please use `#format(#{rules.map { |r| ":#{r} => true" }.join(", ") })'"
993
- rules = rules.inject({}) do |h,s|
994
- h[s] = true
995
- h
996
- end
997
993
  end
998
994
  rules
999
995
  end
@@ -1095,17 +1091,21 @@ class Money
1095
1091
  # build the string based on major/minor since separator/delimiters have been removed
1096
1092
  # avoiding floating point arithmetic here to ensure accuracy
1097
1093
  cents = (major.to_i * currency.subunit_to_unit)
1098
- # add the minor number as well. this may have any number of digits,
1099
- # so we treat minor as a string and truncate or right-fill it with zeroes
1100
- # until it becomes a two-digit number string, which we add to cents.
1094
+ # Because of an bug in JRuby, we can't just call #floor
1095
+ decimal_places = Math.log10(currency.subunit_to_unit).to_s.to_i
1101
1096
  minor = minor.to_s
1102
- truncated_minor = minor[0..1]
1103
- truncated_minor << "0" * (2 - truncated_minor.size) if truncated_minor.size < 2
1104
- cents += truncated_minor.to_i
1105
- # respect rounding rules
1106
- if minor.size >= 3 && minor[2..2].to_i >= 5
1107
- cents += 1
1108
- end
1097
+ minor = if minor.size < decimal_places
1098
+ (minor + ("0" * decimal_places))[0,decimal_places].to_i
1099
+ elsif minor.size > decimal_places
1100
+ if minor[decimal_places,1].to_i >= 5
1101
+ minor[0,decimal_places].to_i+1
1102
+ else
1103
+ minor[0,decimal_places].to_i
1104
+ end
1105
+ else
1106
+ minor.to_i
1107
+ end
1108
+ cents += minor
1109
1109
 
1110
1110
  # if negative, multiply by -1; otherwise, return positive cents
1111
1111
  negative ? cents * -1 : cents
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: money
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
5
4
  prerelease: false
6
5
  segments:
7
6
  - 3
8
- - 1
9
7
  - 5
10
- version: 3.1.5
8
+ - 0
9
+ version: 3.5.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Tobias Luetke
@@ -19,51 +18,64 @@ autorequire:
19
18
  bindir: bin
20
19
  cert_chain: []
21
20
 
22
- date: 2010-10-08 00:00:00 -04:00
21
+ date: 2010-12-15 00:00:00 -05:00
23
22
  default_executable:
24
23
  dependencies:
25
24
  - !ruby/object:Gem::Dependency
26
- name: rspec
25
+ name: i18n
27
26
  prerelease: false
28
27
  requirement: &id001 !ruby/object:Gem::Requirement
29
28
  none: false
30
29
  requirements:
31
- - - ">="
30
+ - - ~>
32
31
  - !ruby/object:Gem::Version
33
- hash: 3
34
32
  segments:
35
33
  - 0
36
- version: "0"
37
- type: :development
34
+ - 4
35
+ version: "0.4"
36
+ type: :runtime
38
37
  version_requirements: *id001
39
38
  - !ruby/object:Gem::Dependency
40
- name: yard
39
+ name: rspec
41
40
  prerelease: false
42
41
  requirement: &id002 !ruby/object:Gem::Requirement
43
42
  none: false
44
43
  requirements:
45
44
  - - ">="
46
45
  - !ruby/object:Gem::Version
47
- hash: 3
48
46
  segments:
47
+ - 2
49
48
  - 0
50
- version: "0"
49
+ - 0
50
+ version: 2.0.0
51
51
  type: :development
52
52
  version_requirements: *id002
53
53
  - !ruby/object:Gem::Dependency
54
- name: json
54
+ name: yard
55
55
  prerelease: false
56
56
  requirement: &id003 !ruby/object:Gem::Requirement
57
57
  none: false
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- hash: 3
62
61
  segments:
63
62
  - 0
64
63
  version: "0"
65
64
  type: :development
66
65
  version_requirements: *id003
66
+ - !ruby/object:Gem::Dependency
67
+ name: json
68
+ prerelease: false
69
+ requirement: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ type: :development
78
+ version_requirements: *id004
67
79
  description: This library aids one in handling money and different currencies.
68
80
  email:
69
81
  - hongli@phusion.nl
@@ -79,8 +91,6 @@ files:
79
91
  - lib/money/bank/variable_exchange.rb
80
92
  - lib/money/core_extensions.rb
81
93
  - lib/money/currency.rb
82
- - lib/money/defaults.rb
83
- - lib/money/deprecations.rb
84
94
  - lib/money/money.rb
85
95
  - lib/money.rb
86
96
  - CHANGELOG.md
@@ -100,7 +110,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
110
  requirements:
101
111
  - - ">="
102
112
  - !ruby/object:Gem::Version
103
- hash: 3
104
113
  segments:
105
114
  - 0
106
115
  version: "0"
@@ -109,7 +118,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
118
  requirements:
110
119
  - - ">="
111
120
  - !ruby/object:Gem::Version
112
- hash: 23
113
121
  segments:
114
122
  - 1
115
123
  - 3
@@ -1,57 +0,0 @@
1
- # encoding: utf-8
2
-
3
- class Money
4
- # Used to notify users about the deprecated constants.
5
- # @see Money::SYMBOLS, Money::SEPARATOR and Money::DELIMITERS
6
- class DeprecatedHash < Hash
7
-
8
- # Creates a new +DeprecatedHash+ with message that will be displayed when
9
- # accessing +#[]+ and +#[]=+.
10
- def initialize(hash, message)
11
- @message = message
12
- replace(hash)
13
- end
14
-
15
- # Displays @message then calls +super+.
16
- def [](key)
17
- Money.deprecate(@message)
18
- super
19
- end
20
-
21
- # Displays @message then calls +super+.
22
- def []=(value)
23
- Money.deprecate(@message)
24
- super
25
- end
26
-
27
- end
28
-
29
- # @deprecated See Money::Currency#symbol
30
- SYMBOLS = DeprecatedHash.new({
31
- "GBP" => "£",
32
- "JPY" => "¥",
33
- "EUR" => "€",
34
- "ZWD" => "Z$",
35
- "CNY" => "¥",
36
- "INR" => "₨",
37
- "NPR" => "₨",
38
- "SCR" => "₨",
39
- "LKR" => "₨",
40
- "SEK" => "kr",
41
- "GHC" => "¢",
42
- "BRL" => "R$ ",
43
- # Everything else defaults to '¤'
44
- }, "Money::SYMBOLS has no longer effect and will be removed in v3.2.0. See Money::Currency#symbol.")
45
-
46
- # @deprecated See Money::Currency#separator
47
- SEPARATORS = DeprecatedHash.new({
48
- "BRL" => ",",
49
- # Everything else defaults to '.'
50
- }, "Money::SEPARATORS is deprecated and will be removed in v3.2.0. See Money::Currency#separator.")
51
-
52
- # @deprecated See Money::Currency#delimiter
53
- DELIMITERS = DeprecatedHash.new({
54
- "BRL" => ".",
55
- # Everything else defaults to ","
56
- }, "Money::DELIMITERS is deprecated and will be removed in Money v3.2.0. See Money::Currency#delimiter.")
57
- end
@@ -1,24 +0,0 @@
1
- class Money
2
- # Displays a deprecation warning message.
3
- #
4
- # @param [String] message The message to display.
5
- #
6
- # @return [nil]
7
- def self.deprecate(message)
8
- warn "DEPRECATION WARNING: #{message}"
9
- end
10
-
11
-
12
- # Money::VariableExchangeBank is the legacy default bank
13
- # shipped with Money. The class has been superseded by
14
- # Money::Bank::VariableExchange.
15
- #
16
- # @deprecated Use Money::Bank::VariableExchange instead.
17
- class VariableExchangeBank < Bank::VariableExchange # :nodoc:
18
- # Calls +Money#deprecate+ the super.
19
- def initialize(*args)
20
- Money.deprecate "Money::VariableExchangeBank is deprecated and will be removed in v3.2.0. Use Money::Bank::VariableExchange instead."
21
- super
22
- end
23
- end
24
- end