Class: Money
- Inherits:
-
Object
- Object
- Money
- Includes:
- Comparable, Arithmetic, Formatting, Parsing
- Defined in:
- lib/money/money.rb,
lib/money/currency.rb,
lib/money/bank/base.rb,
lib/money/money/parsing.rb,
lib/money/money/formatting.rb,
lib/money/money/arithmetic.rb,
lib/money/bank/variable_exchange.rb
Overview
Represents an amount of money in a given currency.
Defined Under Namespace
Modules: Arithmetic, Bank, Formatting, Parsing Classes: Currency
Class Attribute Summary (collapse)
-
+ (true, false) assume_from_symbol
Use this to enable the ability to assume the currency from a passed symbol.
-
+ (Integer) conversion_precision
Use this to specify precision for converting Rational to BigDecimal.
-
+ (Money::Bank::*) default_bank
Each Money object is associated to a bank object, which is responsible for currency exchange.
-
+ (Money::Currency) default_currency
The default currency, which is used when Money.new is called without an explicit currency argument.
-
+ (true, false) infinite_precision
Use this to enable infinite precision cents.
-
+ (BigDecimal::ROUND_MODE) rounding_mode
Use this to specify the rounding mode.
-
+ (true, false) use_i18n
Use this to disable i18n even if it's used by other objects in your app.
Instance Attribute Summary (collapse)
-
- (Money::Bank::*) bank
readonly
The Money::Bank based object used to perform currency exchanges with.
-
- (Currency) currency
readonly
The currency the money is in.
Class Method Summary (collapse)
-
+ (Numeric) add_rate(from_currency, to_currency, rate)
Adds a new exchange rate to the default bank and return the rate.
-
+ (Money) ca_dollar(cents)
Creates a new Money object of the given value, using the Canadian dollar currency.
-
+ (Money) empty(currency = default_currency)
Create a new money object with value 0.
-
+ (Money) euro(cents)
Creates a new Money object of the given value, using the Euro currency.
-
+ (Money) new_with_amount(amount, currency = Money.default_currency, bank = Money.default_bank)
Creates a new Money object of amount value , with given currency.
-
+ (Object) new_with_dollars(*args)
Synonym of #new_with_amount.
-
+ (Money) us_dollar(cents)
Creates a new Money object of the given value, using the American dollar currency.
Instance Method Summary (collapse)
-
- (Array<Money, Money, Money>) allocate(splits)
Allocates money between different parties without loosing pennies.
-
- (Float) amount
Returns the numerical value of the money.
-
- (Money) as_ca_dollar
Receive a money object with the same amount as the current Money object in canadian dollar.
-
- (Money) as_euro
Receive a money object with the same amount as the current Money object in euro.
-
- (Money) as_us_dollar
Receive a money object with the same amount as the current Money object in american dollars.
-
- (Integer) cents
Convenience method for fractional part of the amount.
-
- (String) currency_as_string
Return string representation of currency object.
-
- (Money::Currency) currency_as_string=(val)
Set currency object using a string.
-
- (Float) dollars
Assuming using a currency using dollars: Returns the value of the money in dollars, instead of in the fractional unit cents.
-
- (Money) exchange_to(other_currency)
Receive the amount of this money object in another Currency.
-
- (Integer) fractional
The value of the amount represented in the fractional unit of the currency.
-
- (Fixnum) hash
Returns a Fixnum hash value based on the fractional and currency attributes in order to use functions like & (intersection), group_by, etc.
-
- (Money) initialize(fractional, currency = Money.default_currency, bank = Money.default_bank)
constructor
Creates a new Money object of value given in the fractional unit of the given currency.
-
- (String) inspect
Common inspect function.
- - (Object) localize_formatting_rules(rules)
- - (Object) regexp_format(formatted, rules, decimal_mark, symbol_value)
-
- (Array<Money, Money, Money>) split(num)
Split money amongst parties evenly without loosing pennies.
-
- (String) symbol
Uses Currency#symbol.
-
- (BigDecimal) to_d
Return the amount of money as a BigDecimal.
-
- (Float) to_f
Return the amount of money as a float.
-
- (self) to_money(given_currency = nil)
Conversation to self.
-
- (String) to_s
Returns the amount of money as a string.
Methods included from Parsing
Methods included from Formatting
#decimal_mark, #format, #thousands_separator
Methods included from Arithmetic
#%, #*, #+, #-, #-@, #/, #<=>, #==, #abs, #div, #divmod, #eql?, #modulo, #negative?, #nonzero?, #positive?, #remainder, #zero?
Constructor Details
- (Money) initialize(fractional, currency = Money.default_currency, bank = Money.default_bank)
240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/money/money.rb', line 240 def initialize(fractional, currency = Money.default_currency, bank = Money.default_bank) @fractional = if fractional.is_a?(Rational) fractional.to_d(self.class.conversion_precision) elsif fractional.respond_to?(:to_d) fractional.to_d else BigDecimal.new(fractional.to_s) end @currency = Currency.wrap(currency) @bank = bank end |
Class Attribute Details
+ (true, false) assume_from_symbol
Use this to enable the ability to assume the currency from a passed symbol
71 72 73 |
# File 'lib/money/money.rb', line 71 def assume_from_symbol @assume_from_symbol end |
+ (Integer) conversion_precision
Use this to specify precision for converting Rational to BigDecimal
86 87 88 |
# File 'lib/money/money.rb', line 86 def conversion_precision @conversion_precision end |
+ (Money::Bank::*) default_bank
Each Money object is associated to a bank object, which is responsible for currency exchange. This property allows you to specify the default bank object. The default value for this property is an instance of Bank::VariableExchange. It allows one to specify custom exchange rates.
54 55 56 |
# File 'lib/money/money.rb', line 54 def default_bank @default_bank end |
+ (Money::Currency) default_currency
The default currency, which is used when Money.new is called without an explicit currency argument. The default value is Currency.new(“USD”). The value must be a valid Money::Currency instance.
61 62 63 |
# File 'lib/money/money.rb', line 61 def default_currency @default_currency end |
+ (true, false) infinite_precision
Use this to enable infinite precision cents
76 77 78 |
# File 'lib/money/money.rb', line 76 def infinite_precision @infinite_precision end |
+ (BigDecimal::ROUND_MODE) rounding_mode
Use this to specify the rounding mode
81 82 83 |
# File 'lib/money/money.rb', line 81 def rounding_mode @rounding_mode end |
+ (true, false) use_i18n
Use this to disable i18n even if it's used by other objects in your app.
66 67 68 |
# File 'lib/money/money.rb', line 66 def use_i18n @use_i18n end |
Instance Attribute Details
- (Money::Bank::*) bank (readonly)
The Money::Bank based object used to perform currency exchanges with.
44 45 46 |
# File 'lib/money/money.rb', line 44 def bank @bank end |
- (Currency) currency (readonly)
The currency the money is in.
39 40 41 |
# File 'lib/money/money.rb', line 39 def currency @currency end |
Class Method Details
+ (Numeric) add_rate(from_currency, to_currency, rate)
Adds a new exchange rate to the default bank and return the rate.
213 214 215 |
# File 'lib/money/money.rb', line 213 def self.add_rate(from_currency, to_currency, rate) Money.default_bank.add_rate(from_currency, to_currency, rate) end |
+ (Money) ca_dollar(cents)
Creates a new Money object of the given value, using the Canadian dollar currency.
133 134 135 |
# File 'lib/money/money.rb', line 133 def self.ca_dollar(cents) Money.new(cents, "CAD") end |
+ (Money) empty(currency = default_currency)
Create a new money object with value 0.
118 119 120 |
# File 'lib/money/money.rb', line 118 def self.empty(currency = default_currency) Money.new(0, currency) end |
+ (Money) euro(cents)
Creates a new Money object of the given value, using the Euro currency.
162 163 164 |
# File 'lib/money/money.rb', line 162 def self.euro(cents) Money.new(cents, "EUR") end |
+ (Money) new_with_amount(amount, currency = Money.default_currency, bank = Money.default_bank)
Creates a new Money object of amount value , with given currency.
The amount value is expressed in the main monetary unit, opposite to the subunit-based representation used internally by this library called cents.
189 190 191 192 193 194 |
# File 'lib/money/money.rb', line 189 def self.new_with_amount(amount, currency = Money.default_currency, bank = Money.default_bank) money = from_numeric(amount, currency) # Hack! You can't change a bank money.instance_variable_set("@bank", bank) money end |
+ (Object) new_with_dollars(*args)
Synonym of #new_with_amount
199 200 201 |
# File 'lib/money/money.rb', line 199 def self.new_with_dollars(*args) self.new_with_amount(*args) end |
+ (Money) us_dollar(cents)
Creates a new Money object of the given value, using the American dollar currency.
148 149 150 |
# File 'lib/money/money.rb', line 148 def self.us_dollar(cents) Money.new(cents, "USD") end |
Instance Method Details
- (Array<Money, Money, Money>) allocate(splits)
Allocates money between different parties without loosing pennies. After the mathmatically split has been performed, left over pennies will be distributed round-robin amongst the parties. This means that parties listed first will likely recieve more pennies then ones that are listed later
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 |
# File 'lib/money/money.rb', line 478 def allocate(splits) allocations = splits.inject(BigDecimal("0")) do |sum, n| n = BigDecimal(n.to_s) unless n.is_a?(BigDecimal) sum + n end if (allocations - BigDecimal("1")) > Float::EPSILON raise ArgumentError, "splits add to more then 100%" end left_over = fractional amounts = splits.map do |ratio| if self.class.infinite_precision fraction = fractional * ratio else fraction = (fractional * ratio / allocations).floor left_over -= fraction fraction end end unless self.class.infinite_precision left_over.to_i.times { |i| amounts[i % amounts.length] += 1 } end amounts.collect { |fractional| Money.new(fractional, currency) } end |
- (Float) amount
Returns the numerical value of the money
283 284 285 |
# File 'lib/money/money.rb', line 283 def amount to_f end |
- (Money) as_ca_dollar
Receive a money object with the same amount as the current Money object in canadian dollar.
450 451 452 |
# File 'lib/money/money.rb', line 450 def as_ca_dollar exchange_to("CAD") end |
- (Money) as_euro
Receive a money object with the same amount as the current Money object in euro.
462 463 464 |
# File 'lib/money/money.rb', line 462 def as_euro exchange_to("EUR") end |
- (Money) as_us_dollar
Receive a money object with the same amount as the current Money object in american dollars.
438 439 440 |
# File 'lib/money/money.rb', line 438 def as_us_dollar exchange_to("USD") end |
- (Integer) cents
Convenience method for fractional part of the amount. Synonym of #fractional
17 18 19 |
# File 'lib/money/money.rb', line 17 def cents fractional end |
- (String) currency_as_string
Return string representation of currency object
293 294 295 |
# File 'lib/money/money.rb', line 293 def currency_as_string currency.to_s end |
- (Money::Currency) currency_as_string=(val)
Set currency object using a string
305 306 307 |
# File 'lib/money/money.rb', line 305 def currency_as_string=(val) @currency = Currency.wrap(val) end |
- (Float) dollars
Assuming using a currency using dollars: Returns the value of the money in dollars, instead of in the fractional unit cents.
Synonym of #amount
268 269 270 |
# File 'lib/money/money.rb', line 268 def dollars amount end |
- (Money) exchange_to(other_currency)
Receive the amount of this money object in another Currency.
425 426 427 428 |
# File 'lib/money/money.rb', line 425 def exchange_to(other_currency) other_currency = Currency.wrap(other_currency) @bank.exchange_with(self, other_currency) end |
- (Integer) fractional
The value of the amount represented in the fractional unit of the currency. Example: USD, 1 dollar (amount) == 100 cents (fractional unit).
24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/money/money.rb', line 24 def fractional if self.class.infinite_precision @fractional else # If the Money object is created from a serialized YAML string, # @fractional can end up being set to a Float. We need to ensure # it is BigDecimal before calling #round with two paramers. # Float class only provides #round with 0 or 1 parameter. BigDecimal.new(@fractional.to_s, 0).round(0, self.class.rounding_mode).to_i end end |
- (Fixnum) hash
Returns a Fixnum hash value based on the fractional and currency attributes in order to use functions like & (intersection), group_by, etc.
316 317 318 |
# File 'lib/money/money.rb', line 316 def hash [fractional.hash, currency.hash].hash end |
- (String) inspect
Common inspect function
333 334 335 |
# File 'lib/money/money.rb', line 333 def inspect "#<Money fractional:#{fractional} currency:#{currency}>" end |
- (Object) localize_formatting_rules(rules)
305 306 307 308 309 310 311 312 |
# File 'lib/money/money/formatting.rb', line 305 def localize_formatting_rules(rules) if currency.iso_code == "JPY" && I18n.locale == :ja rules[:symbol] = "円" rules[:symbol_position] = :after rules[:symbol_after_without_space] = true end rules end |
- (Object) regexp_format(formatted, rules, decimal_mark, symbol_value)
291 292 293 294 295 296 297 298 299 300 301 302 303 |
# File 'lib/money/money/formatting.rb', line 291 def regexp_format(formatted, rules, decimal_mark, symbol_value) regexp_decimal = Regexp.escape(decimal_mark) if rules[:south_asian_number_formatting] /(\d+?)(?=(\d\d)+(\d)(?:\.))/ else # Symbols may contain decimal marks (E.g "դր.") if formatted.sub(symbol_value, "") =~ /#{regexp_decimal}/ /(\d)(?=(?:\d{3})+(?:#{regexp_decimal}))/ else /(\d)(?=(?:\d{3})+(?:[^\d]{1}|$))/ end end end |
- (Array<Money, Money, Money>) split(num)
Split money amongst parties evenly without loosing pennies.
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 |
# File 'lib/money/money.rb', line 515 def split(num) raise ArgumentError, "need at least one party" if num < 1 if self.class.infinite_precision amt = self.div(BigDecimal(num.to_s)) return 1.upto(num).map{amt} end low = Money.new(fractional / num, self.currency) high = Money.new(low.fractional + 1, self.currency) remainder = fractional % num result = [] num.times do |index| result[index] = index < remainder ? high : low end result end |
- (String) symbol
Uses Currency#symbol. If nil is returned, defaults to “¤”.
326 327 328 |
# File 'lib/money/money.rb', line 326 def symbol currency.symbol || "¤" end |
- (BigDecimal) to_d
Return the amount of money as a BigDecimal.
387 388 389 |
# File 'lib/money/money.rb', line 387 def to_d BigDecimal.new(fractional.to_s) / BigDecimal.new(currency.subunit_to_unit.to_s) end |
- (Float) to_f
Return the amount of money as a float. Floating points cannot guarantee precision. Therefore, this function should only be used when you no longer need to represent currency or working with another system that requires decimals.
400 401 402 |
# File 'lib/money/money.rb', line 400 def to_f to_d.to_f end |
- (self) to_money(given_currency = nil)
Conversation to self.
407 408 409 410 411 412 413 414 |
# File 'lib/money/money.rb', line 407 def to_money(given_currency = nil) given_currency = Currency.wrap(given_currency) if given_currency if given_currency.nil? || self.currency == given_currency self else exchange_to(given_currency) end end |
- (String) to_s
Returns the amount of money as a string.
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
# File 'lib/money/money.rb', line 343 def to_s unit, subunit = fractional().abs.divmod(currency.subunit_to_unit) unit_str = "" subunit_str = "" fraction_str = "" if self.class.infinite_precision subunit, fraction = subunit.divmod(BigDecimal("1")) unit_str = unit.to_i.to_s subunit_str = subunit.to_i.to_s fraction_str = fraction.to_s("F")[2..-1] # want fractional part "0.xxx" fraction_str = "" if fraction_str =~ /^0+$/ else unit_str, subunit_str = unit.to_s, subunit.to_s end absolute_str = if currency.decimal_places == 0 if fraction_str == "" unit_str else "#{unit_str}#{decimal_mark}#{fraction_str}" end else # need to pad subunit to right position, # for example 1 usd 3 cents should be 1.03 not 1.3 subunit_str.insert(0, '0') while subunit_str.length < currency.decimal_places "#{unit_str}#{decimal_mark}#{subunit_str}#{fraction_str}" end absolute_str.tap do |str| str.insert(0, "-") if fractional() < 0 end end |