money 3.1.0.pre3 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +196 -0
- data/README.md +217 -0
- data/lib/money/bank/base.rb +73 -32
- data/lib/money/bank/variable_exchange.rb +128 -27
- data/lib/money/core_extensions.rb +39 -18
- data/lib/money/currency.rb +146 -53
- data/lib/money/defaults.rb +8 -2
- data/lib/money/deprecations.rb +8 -5
- data/lib/money/money.rb +363 -170
- metadata +45 -54
- data/.document +0 -5
- data/.gitignore +0 -21
- data/CHANGELOG.rdoc +0 -68
- data/README.rdoc +0 -212
- data/Rakefile +0 -49
- data/VERSION +0 -1
- data/money.gemspec +0 -77
- data/spec/bank/base_spec.rb +0 -78
- data/spec/bank/variable_exchange_spec.rb +0 -311
- data/spec/core_extensions_spec.rb +0 -111
- data/spec/currency_spec.rb +0 -126
- data/spec/deprecations_spec.rb +0 -16
- data/spec/money_spec.rb +0 -799
- data/spec/spec_helper.rb +0 -8
data/lib/money/defaults.rb
CHANGED
@@ -1,19 +1,24 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
class Money
|
4
|
-
|
4
|
+
# Used to notify users about the deprecated constants.
|
5
|
+
# @see Money::SYMBOLS, Money::SEPARATOR and Money::DELIMITERS
|
5
6
|
class DeprecatedHash < Hash
|
6
7
|
|
8
|
+
# Creates a new +DeprecatedHash+ with message that will be displayed when
|
9
|
+
# accessing +#[]+ and +#[]=+.
|
7
10
|
def initialize(hash, message)
|
8
11
|
@message = message
|
9
12
|
replace(hash)
|
10
13
|
end
|
11
14
|
|
15
|
+
# Displays @message then calls +super+.
|
12
16
|
def [](key)
|
13
17
|
Money.deprecate(@message)
|
14
18
|
super
|
15
19
|
end
|
16
20
|
|
21
|
+
# Displays @message then calls +super+.
|
17
22
|
def []=(value)
|
18
23
|
Money.deprecate(@message)
|
19
24
|
super
|
@@ -38,14 +43,15 @@ class Money
|
|
38
43
|
# Everything else defaults to '¤'
|
39
44
|
}, "Money::SYMBOLS has no longer effect and will be removed in v3.2.0. See Money::Currency#symbol.")
|
40
45
|
|
46
|
+
# @deprecated See Money::Currency#separator
|
41
47
|
SEPARATORS = DeprecatedHash.new({
|
42
48
|
"BRL" => ",",
|
43
49
|
# Everything else defaults to '.'
|
44
50
|
}, "Money::SEPARATORS is deprecated and will be removed in v3.2.0. See Money::Currency#separator.")
|
45
51
|
|
52
|
+
# @deprecated See Money::Currency#delimiter
|
46
53
|
DELIMITERS = DeprecatedHash.new({
|
47
54
|
"BRL" => ".",
|
48
55
|
# Everything else defaults to ","
|
49
56
|
}, "Money::DELIMITERS is deprecated and will be removed in Money v3.2.0. See Money::Currency#delimiter.")
|
50
|
-
|
51
57
|
end
|
data/lib/money/deprecations.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
class Money
|
2
|
-
|
2
|
+
# Displays a deprecation warning message.
|
3
|
+
#
|
4
|
+
# @param [String] message The message to display.
|
5
|
+
#
|
6
|
+
# @return [nil]
|
3
7
|
def self.deprecate(message)
|
4
8
|
warn "DEPRECATION WARNING: #{message}"
|
5
9
|
end
|
@@ -9,13 +13,12 @@ class Money
|
|
9
13
|
# shipped with Money. The class has been superseded by
|
10
14
|
# Money::Bank::VariableExchange.
|
11
15
|
#
|
12
|
-
# @
|
16
|
+
# @deprecated Use Money::Bank::VariableExchange instead.
|
13
17
|
class VariableExchangeBank < Bank::VariableExchange # :nodoc:
|
18
|
+
# Calls +Money#deprecate+ the super.
|
14
19
|
def initialize(*args)
|
15
|
-
Money.deprecate "Money::VariableExchangeBank is deprecated and will be removed in v3.2.0. "
|
16
|
-
"Use Money::Bank::VariableExchange instead."
|
20
|
+
Money.deprecate "Money::VariableExchangeBank is deprecated and will be removed in v3.2.0. Use Money::Bank::VariableExchange instead."
|
17
21
|
super
|
18
22
|
end
|
19
23
|
end
|
20
|
-
|
21
24
|
end
|
data/lib/money/money.rb
CHANGED
@@ -2,79 +2,132 @@
|
|
2
2
|
require 'money/currency'
|
3
3
|
require 'money/bank/variable_exchange'
|
4
4
|
|
5
|
-
# Represents an amount of money in a
|
5
|
+
# Represents an amount of money in a given currency.
|
6
6
|
class Money
|
7
7
|
include Comparable
|
8
8
|
|
9
|
-
|
9
|
+
# The value of the money is cents.
|
10
|
+
#
|
11
|
+
# @return [Integer]
|
12
|
+
attr_reader :cents
|
13
|
+
|
14
|
+
# The currency the money is in.
|
15
|
+
#
|
16
|
+
# @return [Currency]
|
17
|
+
attr_reader :currency
|
18
|
+
|
19
|
+
# The +Money::Bank+ based object used to perform currency exchanges with.
|
20
|
+
#
|
21
|
+
# @return [Money::Bank::*]
|
22
|
+
attr_reader :bank
|
10
23
|
|
24
|
+
# Class Methods
|
11
25
|
class << self
|
12
26
|
# Each Money object is associated to a bank object, which is responsible
|
13
|
-
# for currency exchange. This property allows
|
14
|
-
# bank object.
|
15
|
-
#
|
16
|
-
# bank1 = MyBank.new
|
17
|
-
# bank2 = MyOtherBank.new
|
18
|
-
#
|
19
|
-
# Money.default_bank = bank1
|
20
|
-
# money1 = Money.new(10)
|
21
|
-
# money1.bank # => bank1
|
22
|
-
#
|
23
|
-
# Money.default_bank = bank2
|
24
|
-
# money2 = Money.new(10)
|
25
|
-
# money2.bank # => bank2
|
26
|
-
# money1.bank # => bank1
|
27
|
+
# for currency exchange. This property allows you to specify the default
|
28
|
+
# bank object. The default value for this property is an instance if
|
29
|
+
# +Bank::VariableExchange.+ It allows one to specify custom exchange rates.
|
27
30
|
#
|
28
|
-
#
|
29
|
-
# It allows one to specify custom exchange rates:
|
30
|
-
#
|
31
|
-
# Money.default_bank.add_rate("USD", "CAD", 1.24515)
|
32
|
-
# Money.default_bank.add_rate("CAD", "USD", 0.803115)
|
33
|
-
# Money.us_dollar(100).exchange_to("CAD") # => Money.ca_dollar(124)
|
34
|
-
# Money.ca_dollar(100).exchange_to("USD") # => Money.us_dollar(80)
|
31
|
+
# @return [Money::Bank::*]
|
35
32
|
attr_accessor :default_bank
|
36
33
|
|
37
|
-
# The default currency, which is used when
|
38
|
-
#
|
39
|
-
#
|
34
|
+
# The default currency, which is used when +Money.new+ is called without an
|
35
|
+
# explicit currency argument. The default value is Currency.new("USD"). The
|
36
|
+
# value must be a valid +Money::Currency+ instance.
|
37
|
+
#
|
38
|
+
# @return [Money::Currency]
|
40
39
|
attr_accessor :default_currency
|
41
40
|
end
|
42
41
|
|
42
|
+
# Set the default bank for creating new +Money+ objects.
|
43
43
|
self.default_bank = Bank::VariableExchange.instance
|
44
|
-
self.default_currency = Currency.new("USD")
|
45
44
|
|
45
|
+
# Set the default currency for creating new +Money+ object.
|
46
|
+
self.default_currency = Currency.new("USD")
|
46
47
|
|
47
48
|
# Create a new money object with value 0.
|
49
|
+
#
|
50
|
+
# @param [Currency, String, Symbol] currency The currency to use.
|
51
|
+
#
|
52
|
+
# @return [Money]
|
53
|
+
#
|
54
|
+
# @example
|
55
|
+
# Money.empty #=> #<Money @cents=0>
|
48
56
|
def self.empty(currency = default_currency)
|
49
57
|
Money.new(0, currency)
|
50
58
|
end
|
51
59
|
|
52
|
-
# Creates a new Money object of the given value, using the Canadian
|
60
|
+
# Creates a new Money object of the given value, using the Canadian
|
61
|
+
# dollar currency.
|
62
|
+
#
|
63
|
+
# @param [Integer] cents The cents value.
|
64
|
+
#
|
65
|
+
# @return [Money]
|
66
|
+
#
|
67
|
+
# @example
|
68
|
+
# n = Money.ca_dollar(100)
|
69
|
+
# n.cents #=> 100
|
70
|
+
# n.currency #=> #<Money::Currency id: cad>
|
53
71
|
def self.ca_dollar(cents)
|
54
72
|
Money.new(cents, "CAD")
|
55
73
|
end
|
56
74
|
|
57
|
-
# Creates a new Money object of the given value, using the American dollar
|
75
|
+
# Creates a new Money object of the given value, using the American dollar
|
76
|
+
# currency.
|
77
|
+
#
|
78
|
+
# @param [Integer] cents The cents value.
|
79
|
+
#
|
80
|
+
# @return [Money]
|
81
|
+
#
|
82
|
+
# @example
|
83
|
+
# n = Money.us_dollar(100)
|
84
|
+
# n.cents #=> 100
|
85
|
+
# n.currency #=> #<Money::Currency id: usd>
|
58
86
|
def self.us_dollar(cents)
|
59
87
|
Money.new(cents, "USD")
|
60
88
|
end
|
61
89
|
|
62
90
|
# Creates a new Money object of the given value, using the Euro currency.
|
91
|
+
#
|
92
|
+
# @param [Integer] cents The cents value.
|
93
|
+
#
|
94
|
+
# @return [Money]
|
95
|
+
#
|
96
|
+
# @example
|
97
|
+
# n = Money.euro(100)
|
98
|
+
# n.cents #=> 100
|
99
|
+
# n.currency #=> #<Money::Currency id: eur>
|
63
100
|
def self.euro(cents)
|
64
101
|
Money.new(cents, "EUR")
|
65
102
|
end
|
66
103
|
|
104
|
+
# Adds a new exchange rate to the default bank and return the rate.
|
105
|
+
#
|
106
|
+
# @param [Currency, String, Symbol] from_currency Currency to exchange from.
|
107
|
+
# @param [Currency, String, Symbol[ to_currency Currency to exchange to.
|
108
|
+
# @param [Numeric] rate Rate to exchange with.
|
109
|
+
#
|
110
|
+
# @return [Numeric]
|
111
|
+
#
|
112
|
+
# @example
|
113
|
+
# Money.add_rate("USD", "CAD", 1.25) #=> 1.25
|
67
114
|
def self.add_rate(from_currency, to_currency, rate)
|
68
115
|
Money.default_bank.add_rate(from_currency, to_currency, rate)
|
69
116
|
end
|
70
117
|
|
71
|
-
|
72
|
-
#
|
73
|
-
#
|
118
|
+
# Creates a new money object. Alternatively you can use the convenience
|
119
|
+
# methods like +Money#ca_dollar+ and +Money#us_dollar+
|
120
|
+
#
|
121
|
+
# @param [Integer] cents The cents value.
|
122
|
+
# @param [optional, Currency, String, Symbol] currency The currency format.
|
123
|
+
# @param [optional, Money::Bank::*] bank The exchange bank to use.
|
124
|
+
#
|
125
|
+
# @return [Money]
|
74
126
|
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
def initialize(cents, currency = Money.default_currency,
|
127
|
+
# @example
|
128
|
+
# Money.new(100) #=> #<Money @cents=100>
|
129
|
+
def initialize(cents, currency = Money.default_currency,
|
130
|
+
bank = Money.default_bank)
|
78
131
|
@cents = cents.round
|
79
132
|
if currency.is_a?(Hash)
|
80
133
|
# Earlier versions of Money wrongly documented the constructor as being able
|
@@ -91,18 +144,38 @@ class Money
|
|
91
144
|
end
|
92
145
|
|
93
146
|
# Return string representation of currency object
|
147
|
+
#
|
148
|
+
# @return [String]
|
149
|
+
#
|
150
|
+
# @example
|
151
|
+
# Money.new(100, :USD).currency_as_string #=> "USD"
|
94
152
|
def currency_as_string
|
95
153
|
self.currency.to_s
|
96
154
|
end
|
97
155
|
|
98
156
|
# Set currency object using a string
|
157
|
+
#
|
158
|
+
# @param [String] val The currency string.
|
159
|
+
#
|
160
|
+
# @return [Money::Currency]
|
161
|
+
#
|
162
|
+
# @example
|
163
|
+
# Money.new(100).currency_as_string("CAD") #=> #<Money::Currency id: cad>
|
99
164
|
def currency_as_string=(val)
|
100
165
|
@currency = Currency.wrap(val)
|
101
166
|
end
|
102
167
|
|
103
|
-
# Checks whether two money objects have the same currency and the same
|
104
|
-
# Checks against money objects with a different currency and checks
|
105
|
-
# objects that do not respond to #to_money will always return false.
|
168
|
+
# Checks whether two money objects have the same currency and the same
|
169
|
+
# amount. Checks against money objects with a different currency and checks
|
170
|
+
# against objects that do not respond to #to_money will always return false.
|
171
|
+
#
|
172
|
+
# @param [Money] other_money Value to compare with.
|
173
|
+
#
|
174
|
+
# @return [Boolean]
|
175
|
+
#
|
176
|
+
# @example
|
177
|
+
# Money.new(100) == Money.new(101) #=> false
|
178
|
+
# Money.new(100) == Money.new(100) #=> true
|
106
179
|
def ==(other_money)
|
107
180
|
if other_money.respond_to?(:to_money)
|
108
181
|
other_money = other_money.to_money
|
@@ -112,30 +185,49 @@ class Money
|
|
112
185
|
end
|
113
186
|
end
|
114
187
|
|
115
|
-
#
|
188
|
+
# Synonymous with +#==+.
|
189
|
+
#
|
190
|
+
# @param [Money] other_money Value to compare with.
|
191
|
+
#
|
192
|
+
# @return [Money]
|
193
|
+
#
|
194
|
+
# @see #==
|
116
195
|
def eql?(other_money)
|
117
196
|
self == other_money
|
118
197
|
end
|
119
198
|
|
120
|
-
# Returns a Fixnum hash value based on the
|
121
|
-
#
|
122
|
-
# & (intersection), group_by, etc.
|
199
|
+
# Returns a Fixnum hash value based on the +cents+ and +currency+ attributes
|
200
|
+
# in order to use functions like & (intersection), group_by, etc.
|
123
201
|
#
|
124
|
-
#
|
125
|
-
# # => [Money.new(1_00, :eur)]
|
202
|
+
# @return [Fixnum]
|
126
203
|
#
|
204
|
+
# @example
|
205
|
+
# Money.new(100).hash #=> 908351
|
127
206
|
def hash
|
128
207
|
[cents.hash, currency.hash].hash
|
129
208
|
end
|
130
209
|
|
131
|
-
# Compares this money object against another object. +other_money+ must
|
132
|
-
# to #to_money.
|
210
|
+
# Compares this money object against another object. +other_money+ must
|
211
|
+
# respond to #to_money. Returns -1 when less than, 0 when equal and 1 when
|
212
|
+
# greater than.
|
133
213
|
#
|
134
|
-
# If +other_money+ is
|
135
|
-
# converted into this money object's currency by calling +
|
214
|
+
# If +other_money+ is a different currency, then +other_money+ will first be
|
215
|
+
# converted into this money object's currency by calling +#exchange+ on
|
216
|
+
# +other_money+.
|
136
217
|
#
|
137
218
|
# Comparisons against objects that do not respond to #to_money will cause an
|
138
|
-
# ArgumentError to be raised.
|
219
|
+
# +ArgumentError+ to be raised.
|
220
|
+
#
|
221
|
+
# @param [Money, #to_money] other_money Value to compare with.
|
222
|
+
#
|
223
|
+
# @return [-1, 0, 1]
|
224
|
+
#
|
225
|
+
# @raise +ArgumentError+
|
226
|
+
#
|
227
|
+
# @example
|
228
|
+
# Money.new(100) <=> 99 #=> 1
|
229
|
+
# Money.new(100) <=> Money.new(100) #=> 0
|
230
|
+
# Money.new(100) <=> "$101.00" #=> -1
|
139
231
|
def <=>(other_money)
|
140
232
|
if other_money.respond_to?(:to_money)
|
141
233
|
other_money = other_money.to_money
|
@@ -149,10 +241,16 @@ class Money
|
|
149
241
|
end
|
150
242
|
end
|
151
243
|
|
152
|
-
# Returns a new Money object containing the sum of the two operands'
|
153
|
-
#
|
154
|
-
#
|
155
|
-
#
|
244
|
+
# Returns a new Money object containing the sum of the two operands' monetary
|
245
|
+
# values. If +other_money+ has a different currency then its monetary value
|
246
|
+
# is automatically exchanged to this object's currency using +exchange_to+.
|
247
|
+
#
|
248
|
+
# @param [Money] other_money Other +Money+ object to add.
|
249
|
+
#
|
250
|
+
# @return [Money]
|
251
|
+
#
|
252
|
+
# @example
|
253
|
+
# Money.new(100) + Money.new(100) #=> #<Money @cents=200>
|
156
254
|
def +(other_money)
|
157
255
|
if currency == other_money.currency
|
158
256
|
Money.new(cents + other_money.cents, other_money.currency)
|
@@ -162,9 +260,16 @@ class Money
|
|
162
260
|
end
|
163
261
|
|
164
262
|
# Returns a new Money object containing the difference between the two
|
165
|
-
# operands' monetary values. If +other_money+ has a different currency
|
166
|
-
#
|
167
|
-
#
|
263
|
+
# operands' monetary values. If +other_money+ has a different currency then
|
264
|
+
# its monetary value is automatically exchanged to this object's currency
|
265
|
+
# using +exchange_to+.
|
266
|
+
#
|
267
|
+
# @param [Money] other_money Other +Money+ object to subtract.
|
268
|
+
#
|
269
|
+
# @return [Money]
|
270
|
+
#
|
271
|
+
# @example
|
272
|
+
# Money.new(100) - Money.new(99) #=> #<Money @cents=1>
|
168
273
|
def -(other_money)
|
169
274
|
if currency == other_money.currency
|
170
275
|
Money.new(cents - other_money.cents, other_money.currency)
|
@@ -173,25 +278,33 @@ class Money
|
|
173
278
|
end
|
174
279
|
end
|
175
280
|
|
176
|
-
#
|
177
|
-
#
|
178
|
-
# Money.new(15_00, "USD").cents # => 15_00
|
179
|
-
def cents
|
180
|
-
@cents
|
181
|
-
end
|
182
|
-
|
183
|
-
# Multiplies the monetary value with the given number and returns a
|
184
|
-
# new Money object with this monetary value and the same currency.
|
281
|
+
# Multiplies the monetary value with the given number and returns a new
|
282
|
+
# +Money+ object with this monetary value and the same currency.
|
185
283
|
#
|
186
284
|
# Multiplying with another Money object is currently not supported.
|
285
|
+
#
|
286
|
+
# @param [Fixnum] fixnum Number to multiply by.
|
287
|
+
#
|
288
|
+
# @return [Money]
|
289
|
+
#
|
290
|
+
# @example
|
291
|
+
# Money.new(100) * 2 #=> #<Money @cents=200>
|
187
292
|
def *(fixnum)
|
188
293
|
Money.new(cents * fixnum, currency)
|
189
294
|
end
|
190
295
|
|
191
|
-
# Divides the monetary value with the given number and returns a
|
192
|
-
#
|
296
|
+
# Divides the monetary value with the given number and returns a new +Money+
|
297
|
+
# object with this monetary value and the same currency. Can also divide by
|
298
|
+
# another +Money+ object to get a ratio. +Money/Numeric+ returns +Money+.
|
299
|
+
# +Money/Money+ returns +Float+
|
193
300
|
#
|
194
|
-
#
|
301
|
+
# @param [Money, Numeric] val Number to divide by.
|
302
|
+
#
|
303
|
+
# @return [Money, Float]
|
304
|
+
#
|
305
|
+
# @example
|
306
|
+
# Money.new(100) / 10 #=> #<Money @cents=10>
|
307
|
+
# Money.new(100) / Money.new(10) #=> 10.0
|
195
308
|
def /(val)
|
196
309
|
if val.is_a?(Money)
|
197
310
|
if currency == val.currency
|
@@ -204,13 +317,27 @@ class Money
|
|
204
317
|
end
|
205
318
|
end
|
206
319
|
|
207
|
-
# Synonym for
|
320
|
+
# Synonym for +#/+.
|
321
|
+
#
|
322
|
+
# @param [Money, Numeric] val Number to divide by.
|
323
|
+
#
|
324
|
+
# @return [Money, Float]
|
325
|
+
#
|
326
|
+
# @see #/
|
208
327
|
def div(val)
|
209
328
|
self / val
|
210
329
|
end
|
211
330
|
|
212
|
-
#
|
213
|
-
# modulus
|
331
|
+
# Divide money by money or fixnum and return array containing quotient and
|
332
|
+
# modulus.
|
333
|
+
#
|
334
|
+
# @param [Money, Fixnum] val Number to divmod by.
|
335
|
+
#
|
336
|
+
# @return [Array<Money,Money>,Array<Fixnum,Money>]
|
337
|
+
#
|
338
|
+
# @example
|
339
|
+
# Money.new(100).divmod(9) #=> [#<Money @cents=11>, #<Money @cents=1>]
|
340
|
+
# Money.new(100).divmod(Money.new(9)) #=> [11, #<Money @cents=1>]
|
214
341
|
def divmod(val)
|
215
342
|
if val.is_a?(Money)
|
216
343
|
a = self.cents
|
@@ -222,17 +349,38 @@ class Money
|
|
222
349
|
end
|
223
350
|
end
|
224
351
|
|
225
|
-
#
|
352
|
+
# Equivalent to +self.divmod(val)[1]+
|
353
|
+
#
|
354
|
+
# @param [Money, Fixnum] val Number take modulo with.
|
355
|
+
#
|
356
|
+
# @return [Money]
|
357
|
+
#
|
358
|
+
# @example
|
359
|
+
# Money.new(100).modulo(9) #=> #<Money @cents=1>
|
360
|
+
# Money.new(100).modulo(Money.new(9)) #=> #<Money @cents=1>
|
226
361
|
def modulo(val)
|
227
362
|
self.divmod(val)[1]
|
228
363
|
end
|
229
364
|
|
230
|
-
#
|
365
|
+
# Synonym for +#modulo+.
|
366
|
+
#
|
367
|
+
# @param [Money, Fixnum] val Number take modulo with.
|
368
|
+
#
|
369
|
+
# @return [Money]
|
370
|
+
#
|
371
|
+
# @see #modulo
|
231
372
|
def %(val)
|
232
373
|
self.modulo(val)
|
233
374
|
end
|
234
375
|
|
235
|
-
#
|
376
|
+
# If different signs +self.modulo(val) - val+ otherwise +self.modulo(val)+
|
377
|
+
#
|
378
|
+
# @param [Money, Fixnum] val Number to rake remainder with.
|
379
|
+
#
|
380
|
+
# @return [Money]
|
381
|
+
#
|
382
|
+
# @example
|
383
|
+
# Money.new(100).remainder(9) #=> #<Money @cents=1>
|
236
384
|
def remainder(val)
|
237
385
|
a, b = self, val
|
238
386
|
b = b.exchange_to(a.currency) if b.is_a?(Money) and a.currency != b.currency
|
@@ -245,142 +393,157 @@ class Money
|
|
245
393
|
a.modulo(b) - (b.is_a?(Money) ? b : Money.new(b, a.currency))
|
246
394
|
end
|
247
395
|
|
248
|
-
# Return absolute value of self as a new Money object
|
396
|
+
# Return absolute value of self as a new Money object.
|
397
|
+
#
|
398
|
+
# @return [Money]
|
399
|
+
#
|
400
|
+
# @example
|
401
|
+
# Money.new(-100).abs #=> #<Money @cents=100>
|
249
402
|
def abs
|
250
403
|
Money.new(self.cents.abs, self.currency)
|
251
404
|
end
|
252
405
|
|
253
|
-
# Test if the money amount is zero
|
406
|
+
# Test if the money amount is zero.
|
407
|
+
#
|
408
|
+
# @return [Boolean]
|
409
|
+
#
|
410
|
+
# @example
|
411
|
+
# Money.new(100).zero? #=> false
|
412
|
+
# Money.new(0).zero? #=> true
|
254
413
|
def zero?
|
255
414
|
cents == 0
|
256
415
|
end
|
257
416
|
|
258
417
|
# Test if the money amount is non-zero. Returns this money object if it is
|
259
|
-
# non-zero, or nil otherwise, like
|
418
|
+
# non-zero, or nil otherwise, like +Numeric#nonzero?+.
|
419
|
+
#
|
420
|
+
# @return [Money, nil]
|
421
|
+
#
|
422
|
+
# @example
|
423
|
+
# Money.new(100).nonzero? #=> #<Money @cents=100>
|
424
|
+
# Money.new(0).nonzero? #=> nil
|
260
425
|
def nonzero?
|
261
426
|
cents != 0 ? self : nil
|
262
427
|
end
|
263
428
|
|
264
|
-
#
|
265
|
-
#
|
266
|
-
#
|
267
|
-
#
|
429
|
+
# Uses +Currency#symbol+. If +nil+ is returned, defaults to "¤".
|
430
|
+
#
|
431
|
+
# @return [String]
|
432
|
+
#
|
433
|
+
# @example
|
434
|
+
# Money.new(100, "USD").symbol #=> "$"
|
268
435
|
def symbol
|
269
436
|
currency.symbol || "¤"
|
270
437
|
end
|
271
438
|
|
272
|
-
# Uses
|
273
|
-
#
|
439
|
+
# Uses +Currency#delimiter+. If +nil+ is returned, default to ",".
|
440
|
+
#
|
441
|
+
# @return [String]
|
442
|
+
#
|
443
|
+
# @example
|
444
|
+
# Money.new(100, "USD").delimiter #=> ","
|
274
445
|
def delimiter
|
275
446
|
currency.delimiter || ","
|
276
447
|
end
|
277
448
|
|
278
|
-
# Uses
|
279
|
-
#
|
449
|
+
# Uses +Currency#separator+. If +nil+ is returned, default to ".".
|
450
|
+
#
|
451
|
+
# @return [String]
|
452
|
+
#
|
453
|
+
# @example
|
454
|
+
# Money.new(100, "USD").separator #=> "."
|
280
455
|
def separator
|
281
456
|
currency.separator || "."
|
282
457
|
end
|
283
458
|
|
284
|
-
# Creates a formatted price string according to several rules.
|
285
|
-
# options are supported: :display_free, :with_currency, :no_cents, :symbol,
|
286
|
-
# :separator, :delimiter and :html.
|
459
|
+
# Creates a formatted price string according to several rules.
|
287
460
|
#
|
288
|
-
#
|
461
|
+
# @param [Hash] *rules The options used to format the string.
|
289
462
|
#
|
290
|
-
#
|
291
|
-
# supplied string.
|
463
|
+
# @return [String]
|
292
464
|
#
|
293
|
-
#
|
294
|
-
#
|
295
|
-
# Money.us_dollar(0).format => "$0.00"
|
465
|
+
# @option *rules [Boolean, String] :display_free (false) Whether a zero
|
466
|
+
# amount of money should be formatted of "free" or as the supplied string.
|
296
467
|
#
|
297
|
-
#
|
468
|
+
# @example
|
469
|
+
# Money.us_dollar(0).format(:display_free => true) #=> "free"
|
470
|
+
# Money.us_dollar(0).format(:display_free => "gratis") #=> "gratis"
|
471
|
+
# Money.us_dollar(0).format #=> "$0.00"
|
298
472
|
#
|
299
|
-
#
|
473
|
+
# @option *rules [Boolean] :with_currency (false) Whether the currency name
|
474
|
+
# should be appended to the result string.
|
300
475
|
#
|
476
|
+
# @example
|
301
477
|
# Money.ca_dollar(100).format => "$1.00"
|
302
|
-
# Money.ca_dollar(100).format(:with_currency => true)
|
303
|
-
# Money.us_dollar(85).format(:with_currency => true)
|
304
|
-
#
|
305
|
-
# === +:no_cents+
|
478
|
+
# Money.ca_dollar(100).format(:with_currency => true) #=> "$1.00 CAD"
|
479
|
+
# Money.us_dollar(85).format(:with_currency => true) #=> "$0.85 USD"
|
306
480
|
#
|
307
|
-
# Whether cents should be omitted.
|
481
|
+
# @option *rules [Boolean] :no_cents (false) Whether cents should be omitted.
|
308
482
|
#
|
309
|
-
#
|
310
|
-
# Money.ca_dollar(
|
483
|
+
# @example
|
484
|
+
# Money.ca_dollar(100).format(:no_cents => true) #=> "$1"
|
485
|
+
# Money.ca_dollar(599).format(:no_cents => true) #=> "$5"
|
311
486
|
#
|
312
|
-
#
|
313
|
-
#
|
487
|
+
# @option *rules [Boolean, String, nil] :symbol (true) Whether a money symbol
|
488
|
+
# should be prepended to the result string. The default is true. This method
|
489
|
+
# attempts to pick a symbol that's suitable for the given currency.
|
314
490
|
#
|
315
|
-
#
|
316
|
-
#
|
317
|
-
#
|
318
|
-
#
|
319
|
-
#
|
320
|
-
# Money.new(100, "USD") => "$1.00"
|
321
|
-
# Money.new(100, "GBP") => "£1.00"
|
322
|
-
# Money.new(100, "EUR") => "€1.00"
|
491
|
+
# @example
|
492
|
+
# Money.new(100, "USD") #=> "$1.00"
|
493
|
+
# Money.new(100, "GBP") #=> "£1.00"
|
494
|
+
# Money.new(100, "EUR") #=> "€1.00"
|
323
495
|
#
|
324
496
|
# # Same thing.
|
325
|
-
# Money.new(100, "USD").format(:symbol => true)
|
326
|
-
# Money.new(100, "GBP").format(:symbol => true)
|
327
|
-
# Money.new(100, "EUR").format(:symbol => true)
|
328
|
-
#
|
329
|
-
# You can specify a false expression or an empty string to disable prepending
|
330
|
-
# a money symbol:
|
331
|
-
#
|
332
|
-
# Money.new(100, "USD").format(:symbol => false) => "1.00"
|
333
|
-
# Money.new(100, "GBP").format(:symbol => nil) => "1.00"
|
334
|
-
# Money.new(100, "EUR").format(:symbol => "") => "1.00"
|
335
|
-
#
|
336
|
-
#
|
337
|
-
# If the symbol for the given currency isn't known, then it will default
|
338
|
-
# to "¤" as symbol:
|
339
|
-
#
|
340
|
-
# Money.new(100, "AWG").format(:symbol => true) => "¤1.00"
|
341
|
-
#
|
342
|
-
# You can specify a string as value to enforce using a particular symbol:
|
497
|
+
# Money.new(100, "USD").format(:symbol => true) #=> "$1.00"
|
498
|
+
# Money.new(100, "GBP").format(:symbol => true) #=> "£1.00"
|
499
|
+
# Money.new(100, "EUR").format(:symbol => true) #=> "€1.00"
|
343
500
|
#
|
344
|
-
#
|
501
|
+
# # You can specify a false expression or an empty string to disable
|
502
|
+
# # prepending a money symbol.
|
503
|
+
# Money.new(100, "USD").format(:symbol => false) #=> "1.00"
|
504
|
+
# Money.new(100, "GBP").format(:symbol => nil) #=> "1.00"
|
505
|
+
# Money.new(100, "EUR").format(:symbol => "") #=> "1.00"
|
345
506
|
#
|
346
|
-
#
|
507
|
+
# # If the symbol for the given currency isn't known, then it will default
|
508
|
+
# # to "¤" as symbol.
|
509
|
+
# Money.new(100, "AWG").format(:symbol => true) #=> "¤1.00"
|
347
510
|
#
|
348
|
-
#
|
511
|
+
# # You can specify a string as value to enforce using a particular symbol.
|
512
|
+
# Money.new(100, "AWG").format(:symbol => "ƒ") #=> "ƒ1.00"
|
349
513
|
#
|
350
|
-
#
|
514
|
+
# @option *rules [Boolean, String, nil] :separator (true) Whether the
|
515
|
+
# currency should be separated by the specified character or '.'
|
351
516
|
#
|
352
|
-
#
|
517
|
+
# @example
|
518
|
+
# # If a string is specified, it's value is used.
|
519
|
+
# Money.new(100, "USD").format(:separator => ",") #=> "$1,00"
|
353
520
|
#
|
354
|
-
# If the separator for a given currency isn't known, then it will default
|
355
|
-
# "." as separator
|
521
|
+
# # If the separator for a given currency isn't known, then it will default
|
522
|
+
# # to "." as separator.
|
523
|
+
# Money.new(100, "FOO").format #=> "$1.00"
|
356
524
|
#
|
357
|
-
#
|
525
|
+
# @option *rules [Boolean, String, nil] :delimiter (true) Whether the
|
526
|
+
# currency should be delimited by the specified character or ','
|
358
527
|
#
|
359
|
-
#
|
528
|
+
# @example
|
529
|
+
# # If false is specified, no delimiter is used.
|
530
|
+
# Money.new(100000, "USD").format(:delimiter => false) #=> "1000.00"
|
531
|
+
# Money.new(100000, "USD").format(:delimiter => nil) #=> "1000.00"
|
532
|
+
# Money.new(100000, "USD").format(:delimiter => "") #=> "1000.00"
|
360
533
|
#
|
361
|
-
#
|
534
|
+
# # If a string is specified, it's value is used.
|
535
|
+
# Money.new(100000, "USD").format(:delimiter => ".") #=> "$1.000.00"
|
362
536
|
#
|
363
|
-
# If
|
537
|
+
# # If the delimiter for a given currency isn't known, then it will default
|
538
|
+
# # to "," as delimiter.
|
539
|
+
# Money.new(100000, "FOO").format #=> "$1,000.00"
|
364
540
|
#
|
365
|
-
#
|
366
|
-
#
|
367
|
-
# Money.new(100000, "USD").format(:delimiter => "") => "1000.00"
|
541
|
+
# @option *rules [Boolean] :html (false) Whether the currency should be
|
542
|
+
# HTML-formatted. Only useful in combination with +:with_currency+.
|
368
543
|
#
|
369
|
-
#
|
370
|
-
#
|
371
|
-
#
|
372
|
-
#
|
373
|
-
# If the delimiter for a given currency isn't known, then it will default to
|
374
|
-
# "," as delimiter:
|
375
|
-
#
|
376
|
-
# Money.new(100000, "FOO").format => "$1,000.00"
|
377
|
-
#
|
378
|
-
# === +:html+
|
379
|
-
#
|
380
|
-
# Whether the currency should be HTML-formatted. Only useful in combination with +:with_currency+.
|
381
|
-
#
|
382
|
-
# Money.ca_dollar(570).format(:html => true, :with_currency => true)
|
383
|
-
# # => "$5.70 <span class=\"currency\">CAD</span>"
|
544
|
+
# @example
|
545
|
+
# s = Money.ca_dollar(570).format(:html => true, :with_currency => true)
|
546
|
+
# s #=> "$5.70 <span class=\"currency\">CAD</span>"
|
384
547
|
def format(*rules)
|
385
548
|
# support for old format parameters
|
386
549
|
rules = normalize_formatting_rules(rules)
|
@@ -444,8 +607,10 @@ class Money
|
|
444
607
|
|
445
608
|
# Returns the amount of money as a string.
|
446
609
|
#
|
447
|
-
#
|
610
|
+
# @return [String]
|
448
611
|
#
|
612
|
+
# @example
|
613
|
+
# Money.ca_dollar(100).to_s #=> "1.00"
|
449
614
|
def to_s
|
450
615
|
return sprintf("%d", cents) if currency.subunit_to_unit == 1
|
451
616
|
sprintf("%.2f", cents.to_f / currency.subunit_to_unit)
|
@@ -456,49 +621,78 @@ class Money
|
|
456
621
|
# need to represent currency or working with another system that requires
|
457
622
|
# decimals.
|
458
623
|
#
|
459
|
-
#
|
624
|
+
# @return [Float]
|
460
625
|
#
|
626
|
+
# @example
|
627
|
+
# Money.us_dollar(100).to_f => 1.0
|
461
628
|
def to_f
|
462
629
|
cents.to_f / currency.subunit_to_unit
|
463
630
|
end
|
464
631
|
|
465
632
|
# Receive the amount of this money object in another Currency.
|
466
|
-
# <tt>other_currency</tt> can be either a <tt>String</tt>
|
467
|
-
# or a <tt>Currency</tt> instance.
|
468
633
|
#
|
634
|
+
# @param [Currency, String, Symbol] other_currency Currency to exchange to.
|
635
|
+
#
|
636
|
+
# @return [Money]
|
637
|
+
#
|
638
|
+
# @example
|
469
639
|
# Money.new(2000, "USD").exchange_to("EUR")
|
470
640
|
# Money.new(2000, "USD").exchange_to(Currency.new("EUR"))
|
471
|
-
#
|
472
641
|
def exchange_to(other_currency)
|
473
642
|
other_currency = Currency.wrap(other_currency)
|
474
643
|
@bank.exchange_with(self, other_currency)
|
475
644
|
end
|
476
645
|
|
477
646
|
# Receive a money object with the same amount as the current Money object
|
478
|
-
# in american
|
647
|
+
# in american dollars.
|
648
|
+
#
|
649
|
+
# @return [Money]
|
650
|
+
#
|
651
|
+
# @example
|
652
|
+
# n = Money.new(100, "CAD").as_us_dollar
|
653
|
+
# n.currency #=> #<Money::Currency id: usd>
|
479
654
|
def as_us_dollar
|
480
655
|
exchange_to("USD")
|
481
656
|
end
|
482
657
|
|
483
658
|
# Receive a money object with the same amount as the current Money object
|
484
|
-
# in canadian dollar
|
659
|
+
# in canadian dollar.
|
660
|
+
#
|
661
|
+
# @return [Money]
|
662
|
+
#
|
663
|
+
# @example
|
664
|
+
# n = Money.new(100, "USD").as_ca_dollar
|
665
|
+
# n.currency #=> #<Money::Currency id: cad>
|
485
666
|
def as_ca_dollar
|
486
667
|
exchange_to("CAD")
|
487
668
|
end
|
488
669
|
|
489
670
|
# Receive a money object with the same amount as the current Money object
|
490
|
-
# in euro
|
671
|
+
# in euro.
|
672
|
+
#
|
673
|
+
# @return [Money]
|
674
|
+
#
|
675
|
+
# @example
|
676
|
+
# n = Money.new(100, "USD").as_euro
|
677
|
+
# n.currency #=> #<Money::Currency id: eur>
|
491
678
|
def as_euro
|
492
679
|
exchange_to("EUR")
|
493
680
|
end
|
494
681
|
|
495
|
-
# Conversation to self
|
682
|
+
# Conversation to +self+.
|
683
|
+
#
|
684
|
+
# @return [self]
|
496
685
|
def to_money
|
497
686
|
self
|
498
687
|
end
|
499
688
|
|
500
689
|
private
|
501
690
|
|
691
|
+
# Cleans up formatting rules.
|
692
|
+
#
|
693
|
+
# @param [Hash]
|
694
|
+
#
|
695
|
+
# @return [Hash]
|
502
696
|
def normalize_formatting_rules(rules)
|
503
697
|
if rules.size == 1
|
504
698
|
rules = rules.pop
|
@@ -511,5 +705,4 @@ class Money
|
|
511
705
|
end
|
512
706
|
rules
|
513
707
|
end
|
514
|
-
|
515
708
|
end
|