Class: Money
- Inherits:
-
Object
- Object
- Money
- Includes:
- Comparable
- Defined in:
- lib/money/money.rb,
lib/money/currency.rb,
lib/money/bank/base.rb,
lib/money/bank/variable_exchange.rb
Overview
encoding: utf-8
Defined Under Namespace
Modules: Bank Classes: Currency
Class Attribute Summary (collapse)
-
+ (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.
Instance Attribute Summary (collapse)
-
- (Money::Bank::*) bank
readonly
The Money::Bank based object used to perform currency exchanges with.
-
- (Integer) cents
readonly
The value of the money in cents.
-
- (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) from_bigdecimal(value, currency = Money.default_currency)
Converts a BigDecimal into a Money object treating the value as dollars and converting them to the corresponding cents value, according to currency subunit property, before instantiating the Money object.
-
+ (Money) from_fixnum(value, currency = Money.default_currency)
Converts a Fixnum into a Money object treating the value as dollars and converting them to the corresponding cents value, according to currency subunit property, before instantiating the Money object.
-
+ (Money) from_float(value, currency = Money.default_currency)
Converts a Float into a Money object treating the value as dollars and converting them to the corresponding cents value, according to currency subunit property, before instantiating the Money object.
-
+ (Money) from_numeric(value, currency = Money.default_currency)
Converts a Numeric value into a Money object treating the value as dollars and converting them to the corresponding cents value, according to currency subunit property, before instantiating the Money object.
-
+ (Money) from_string(value, currency = Money.default_currency)
Converts a String into a Money object treating the value as dollars and converting them to the corresponding cents value, according to currency subunit property, before instantiating the Money object.
-
+ (Money) new_with_dollars(amount, currency = Money.default_currency, bank = Money.default_bank)
Creates a new Money object of amount value in dollars, with given currency.
-
+ (Money) parse(input, currency = nil)
Parses the current string and converts it to a Money object.
-
+ (Money) us_dollar(cents)
Creates a new Money object of the given value, using the American dollar currency.
Instance Method Summary (collapse)
-
- (Money) %(val)
Synonym for #modulo.
-
- (Money) *(value)
Multiplies the monetary value with the given number and returns a new Money object with this monetary value and the same currency.
-
- (Money) +(other_money)
Returns a new Money object containing the sum of the two operands’ monetary values.
-
- (Money) -(other_money)
Returns a new Money object containing the difference between the two operands’ monetary values.
-
- (Money, Float) /(value)
Divides the monetary value with the given number and returns a new Money object with this monetary value and the same currency.
-
- (-1, ...) <=>(other_money)
Compares this money object against another object.
-
- (Boolean) ==(other_money)
Checks whether two money objects have the same currency and the same amount.
-
- (Money) abs
Return absolute value of self as a new Money object.
-
- (Array<Money, Money, Money>) allocate(splits)
Allocates money between different parties without loosing pennies.
-
- (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.
-
- (String) currency_as_string
Return string representation of currency object.
-
- (Money::Currency) currency_as_string=(val)
Set currency object using a string.
- - (Object) decimal_mark (also: #separator)
-
- (Money, Float) div(value)
Synonym for #/.
-
- (Array<Money,Money>, Array<Fixnum,Money>) divmod(val)
Divide money by money or fixnum and return array containing quotient and modulus.
-
- (Float) dollars
Returns the value of the money in dollars, instead of in cents.
-
- (Money) eql?(other_money)
Synonymous with #==.
-
- (Money) exchange_to(other_currency)
Receive the amount of this money object in another Currency.
-
- (String) format(*rules)
Creates a formatted price string according to several rules.
-
- (Fixnum) hash
Returns a Fixnum hash value based on the cents and currency attributes in order to use functions like & (intersection), group_by, etc.
-
- (Money) initialize(cents, currency = Money.default_currency, bank = Money.default_bank)
constructor
Creates a new Money object of cents value in cents, with given currency.
-
- (String) inspect
Common inspect function.
-
- (Money) modulo(val)
Equivalent to self.divmod(val)[1].
-
- (Money?) nonzero?
Test if the money amount is non-zero.
-
- (Money) remainder(val)
If different signs self.modulo(val) - val otherwise self.modulo(val).
-
- (Array<Money, Money, Money>) split(num)
Split money amongst parties evenly without loosing pennies.
-
- (String) symbol
Uses Currency#symbol.
- - (Object) thousands_separator (also: #delimiter)
-
- (Float) to_f
Return the amount of money as a float.
-
- (self) to_money
Conversation to self.
-
- (String) to_s
Returns the amount of money as a string.
-
- (Boolean) zero?
Test if the money amount is zero.
Constructor Details
- (Money) initialize(cents, currency = Money.default_currency, bank = Money.default_bank)
388 389 390 391 392 |
# File 'lib/money/money.rb', line 388 def initialize(cents, currency = Money.default_currency, bank = Money.default_bank) @cents = cents.round.to_i @currency = Currency.wrap(currency) @bank = bank end |
Class Attribute Details
+ (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 if Bank::VariableExchange. It allows one to specify custom exchange rates.
31 32 33 |
# File 'lib/money/money.rb', line 31 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.
38 39 40 |
# File 'lib/money/money.rb', line 38 def default_currency @default_currency end |
Instance Attribute Details
- (Money::Bank::*) bank (readonly)
The Money::Bank based object used to perform currency exchanges with.
21 22 23 |
# File 'lib/money/money.rb', line 21 def bank @bank end |
- (Integer) cents (readonly)
The value of the money in cents.
11 12 13 |
# File 'lib/money/money.rb', line 11 def cents @cents end |
- (Currency) currency (readonly)
The currency the money is in.
16 17 18 |
# File 'lib/money/money.rb', line 16 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.
361 362 363 |
# File 'lib/money/money.rb', line 361 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.
70 71 72 |
# File 'lib/money/money.rb', line 70 def self.ca_dollar(cents) Money.new(cents, "CAD") end |
+ (Money) empty(currency = default_currency)
Create a new money object with value 0.
55 56 57 |
# File 'lib/money/money.rb', line 55 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.
99 100 101 |
# File 'lib/money/money.rb', line 99 def self.euro(cents) Money.new(cents, "EUR") end |
+ (Money) from_bigdecimal(value, currency = Money.default_currency)
Converts a BigDecimal into a Money object treating the value as dollars and converting them to the corresponding cents value, according to currency subunit property, before instantiating the Money object.
300 301 302 303 304 |
# File 'lib/money/money.rb', line 300 def self.from_bigdecimal(value, currency = Money.default_currency) currency = Money::Currency.wrap(currency) amount = value * currency.subunit_to_unit Money.new(amount.fix, currency) end |
+ (Money) from_fixnum(value, currency = Money.default_currency)
Converts a Fixnum into a Money object treating the value as dollars and converting them to the corresponding cents value, according to currency subunit property, before instantiating the Money object.
241 242 243 244 245 |
# File 'lib/money/money.rb', line 241 def self.from_fixnum(value, currency = Money.default_currency) currency = Money::Currency.wrap(currency) amount = value * currency.subunit_to_unit Money.new(amount, currency) end |
+ (Money) from_float(value, currency = Money.default_currency)
Converts a Float into a Money object treating the value as dollars and converting them to the corresponding cents value, according to currency subunit property, before instantiating the Money object.
Behind the scenes, this method relies on Money.from_bigdecimal to avoid problems with floating point precision.
273 274 275 |
# File 'lib/money/money.rb', line 273 def self.from_float(value, currency = Money.default_currency) from_bigdecimal(BigDecimal.new(value.to_s), currency) end |
+ (Money) from_numeric(value, currency = Money.default_currency)
Converts a Numeric value into a Money object treating the value as dollars and converting them to the corresponding cents value, according to currency subunit property, before instantiating the Money object.
This method relies on various Money.from_* methods and tries to forwards the call to the most appropriate method in order to reduce computation effort. For instance, if value is an Integer, this method calls from_fixnum instead of using the default from_bigdecimal which adds the overload to converts the value into a slower BigDecimal instance.
339 340 341 342 343 344 345 346 347 348 |
# File 'lib/money/money.rb', line 339 def self.from_numeric(value, currency = Money.default_currency) case value when Fixnum from_fixnum(value, currency) when Numeric from_bigdecimal(BigDecimal.new(value.to_s), currency) else raise ArgumentError, "`value' should be a Numeric object" end end |
+ (Money) from_string(value, currency = Money.default_currency)
Converts a String into a Money object treating the value as dollars and converting them to the corresponding cents value, according to currency subunit property, before instantiating the Money object.
Behind the scenes, this method relies on from_bigdecimal to avoid problems with string-to-numeric conversion.
214 215 216 |
# File 'lib/money/money.rb', line 214 def self.from_string(value, currency = Money.default_currency) from_bigdecimal(BigDecimal.new(value.to_s), currency) end |
+ (Money) new_with_dollars(amount, currency = Money.default_currency, bank = Money.default_bank)
Creates a new Money object of amount value in dollars, with given currency.
The amount value is expressed in dollars where the dollar is the main monetary unit, opposite to the subunit-based representation used internally by this library called cents.
128 129 130 131 132 133 |
# File 'lib/money/money.rb', line 128 def self.new_with_dollars(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 |
+ (Money) parse(input, currency = nil)
Parses the current string and converts it to a Money object. Excess characters will be discarded.
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/money/money.rb', line 162 def self.parse(input, currency = nil) i = input.to_s # Get the currency. m = i.scan /([A-Z]{2,3})/ c = m[0] ? m[0][0] : nil # check that currency passed and embedded currency are the same, # and negotiate the final currency if currency.nil? and c.nil? currency = Money.default_currency elsif currency.nil? currency = c elsif c.nil? currency = currency elsif currency != c # TODO: ParseError raise ArgumentError, "Mismatching Currencies" end currency = Money::Currency.wrap(currency) cents = extract_cents(i, currency) Money.new(cents, currency) end |
+ (Money) us_dollar(cents)
Creates a new Money object of the given value, using the American dollar currency.
85 86 87 |
# File 'lib/money/money.rb', line 85 def self.us_dollar(cents) Money.new(cents, "USD") end |
Instance Method Details
- (Money) %(val)
Synonym for #modulo.
648 649 650 |
# File 'lib/money/money.rb', line 648 def %(val) self.modulo(val) end |
- (Money) *(value)
Multiplies the monetary value with the given number and returns a new Money object with this monetary value and the same currency.
Note that you can’t multiply a Money object by an other Money object.
559 560 561 562 563 564 565 |
# File 'lib/money/money.rb', line 559 def *(value) if value.is_a?(Money) raise ArgumentError, "Can't multiply a Money by a Money" else Money.new(cents * value, currency) end end |
- (Money) +(other_money)
Returns a new Money object containing the sum of the two operands’ monetary values. If other_money has a different currency then its monetary value is automatically exchanged to this object’s currency using exchange_to.
518 519 520 521 522 523 524 |
# File 'lib/money/money.rb', line 518 def +(other_money) if currency == other_money.currency Money.new(cents + other_money.cents, other_money.currency) else Money.new(cents + other_money.exchange_to(currency).cents, currency) end end |
- (Money) -(other_money)
Returns a new Money object containing the difference between the two operands’ monetary values. If other_money has a different currency then its monetary value is automatically exchanged to this object’s currency using exchange_to.
537 538 539 540 541 542 543 |
# File 'lib/money/money.rb', line 537 def -(other_money) if currency == other_money.currency Money.new(cents - other_money.cents, other_money.currency) else Money.new(cents - other_money.exchange_to(currency).cents, currency) end end |
- (Money, Float) /(value)
Divides the monetary value with the given number and returns a new Money object with this monetary value and the same currency. Can also divide by another Money object to get a ratio.
Money/Numeric returns Money. Money/Money returns Float.
582 583 584 585 586 587 588 589 590 591 592 |
# File 'lib/money/money.rb', line 582 def /(value) if value.is_a?(Money) if currency == value.currency (cents / BigDecimal.new(value.cents.to_s)).to_f else (cents / BigDecimal(value.exchange_to(currency).cents.to_s)).to_f end else Money.new(cents / value, currency) end end |
- (-1, ...) <=>(other_money)
Compares this money object against another object. other_money must respond to #to_money. Returns -1 when less than, 0 when equal and 1 when greater than.
If other_money is a different currency, then other_money will first be converted into this money object’s currency by calling #exchange on other_money.
Comparisons against objects that do not respond to #to_money will cause an ArgumentError to be raised.
495 496 497 498 499 500 501 502 503 504 505 506 |
# File 'lib/money/money.rb', line 495 def <=>(other_money) if other_money.respond_to?(:to_money) other_money = other_money.to_money if self.currency == other_money.currency cents <=> other_money.cents else cents <=> other_money.exchange_to(currency).cents end else raise ArgumentError, "Comparison of #{self.class} with #{other_money.inspect} failed" end end |
- (Boolean) ==(other_money)
Checks whether two money objects have the same currency and the same amount. Checks against money objects with a different currency and checks against objects that do not respond to #to_money will always return false.
443 444 445 446 447 448 449 450 |
# File 'lib/money/money.rb', line 443 def ==(other_money) if other_money.respond_to?(:to_money) other_money = other_money.to_money cents == other_money.cents && self.currency == other_money.currency else false end end |
- (Money) abs
Return absolute value of self as a new Money object.
678 679 680 |
# File 'lib/money/money.rb', line 678 def abs Money.new(self.cents.abs, self.currency) end |
- (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
1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 |
# File 'lib/money/money.rb', line 1021 def allocate(splits) allocations = splits.inject(0.0) {|sum, i| sum += i } raise ArgumentError, "splits add to more then 100%" if (allocations - 1.0) > Float::EPSILON left_over = cents amounts = splits.collect do |ratio| fraction = (cents * ratio / allocations).floor left_over -= fraction fraction end left_over.times { |i| amounts[i % amounts.length] += 1 } return amounts.collect { |cents| Money.new(cents, currency) } end |
- (Money) as_ca_dollar
Receive a money object with the same amount as the current Money object in canadian dollar.
979 980 981 |
# File 'lib/money/money.rb', line 979 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.
991 992 993 |
# File 'lib/money/money.rb', line 991 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.
967 968 969 |
# File 'lib/money/money.rb', line 967 def as_us_dollar exchange_to("USD") end |
- (String) currency_as_string
Return string representation of currency object
416 417 418 |
# File 'lib/money/money.rb', line 416 def currency_as_string self.currency.to_s end |
- (Money::Currency) currency_as_string=(val)
Set currency object using a string
428 429 430 |
# File 'lib/money/money.rb', line 428 def currency_as_string=(val) @currency = Currency.wrap(val) end |
- (Object) decimal_mark Also known as: separator
743 744 745 |
# File 'lib/money/money.rb', line 743 def decimal_mark currency.decimal_mark || "." end |
- (Money, Float) div(value)
Synonym for #/.
603 604 605 |
# File 'lib/money/money.rb', line 603 def div(value) self / value end |
- (Array<Money,Money>, Array<Fixnum,Money>) divmod(val)
Divide money by money or fixnum and return array containing quotient and modulus.
617 618 619 620 621 622 623 624 625 626 |
# File 'lib/money/money.rb', line 617 def divmod(val) if val.is_a?(Money) a = self.cents b = self.currency == val.currency ? val.cents : val.exchange_to(self.currency).cents q, m = a.divmod(b) return [q, Money.new(m, self.currency)] else return [self.div(val), Money.new(self.cents.modulo(val), self.currency)] end end |
- (Float) dollars
Returns the value of the money in dollars, instead of in cents.
406 407 408 |
# File 'lib/money/money.rb', line 406 def dollars to_f end |
- (Money) eql?(other_money)
Synonymous with #==.
459 460 461 |
# File 'lib/money/money.rb', line 459 def eql?(other_money) self == other_money end |
- (Money) exchange_to(other_currency)
Receive the amount of this money object in another Currency.
954 955 956 957 |
# File 'lib/money/money.rb', line 954 def exchange_to(other_currency) other_currency = Currency.wrap(other_currency) @bank.exchange_with(self, other_currency) end |
- (String) format(*rules)
Creates a formatted price string according to several rules.
841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 |
# File 'lib/money/money.rb', line 841 def format(*rules) # support for old format parameters rules = normalize_formatting_rules(rules) if cents == 0 if rules[:display_free].respond_to?(:to_str) return rules[:display_free] elsif rules[:display_free] return "free" end end symbol_value = if rules.has_key?(:symbol) if rules[:symbol] === true symbol elsif rules[:symbol] rules[:symbol] else "" end elsif rules[:html] currency.html_entity else symbol end formatted = case rules[:no_cents] when true "#{self.to_s.to_i}" else "#{self.to_s}" end symbol_position = if rules.has_key?(:symbol_position) rules[:symbol_position] elsif currency.symbol_first? :before else :after end if symbol_value && !symbol_value.empty? formatted = (symbol_position == :before ? "#{symbol_value}#{formatted}" : "#{formatted} #{symbol_value}") end if rules.has_key?(:decimal_mark) and rules[:decimal_mark] and rules[:decimal_mark] != decimal_mark formatted.sub!(decimal_mark, rules[:decimal_mark]) end thousands_separator_value = thousands_separator # Determine thousands_separator if rules.has_key?(:thousands_separator) if rules[:thousands_separator] === false or rules[:thousands_separator].nil? thousands_separator_value = "" elsif rules[:thousands_separator] thousands_separator_value = rules[:thousands_separator] end end # Apply thousands_separator formatted.gsub!(/(\d)(?=(?:\d{3})+(?:[^\d]|$))/, "\\1#{thousands_separator_value}") if rules[:with_currency] formatted << " " formatted << '<span class="currency">' if rules[:html] formatted << currency.to_s formatted << '</span>' if rules[:html] end formatted end |
- (Fixnum) hash
Returns a Fixnum hash value based on the cents and currency attributes in order to use functions like & (intersection), group_by, etc.
470 471 472 |
# File 'lib/money/money.rb', line 470 def hash [cents.hash, currency.hash].hash end |
- (String) inspect
Common inspect function
1005 1006 1007 |
# File 'lib/money/money.rb', line 1005 def inspect "#<Money cents:#{cents} currency:#{currency}>" end |
- (Money) modulo(val)
Equivalent to self.divmod(val)[1]
637 638 639 |
# File 'lib/money/money.rb', line 637 def modulo(val) self.divmod(val)[1] end |
- (Money?) nonzero?
Test if the money amount is non-zero. Returns this money object if it is non-zero, or nil otherwise, like Numeric#nonzero?.
701 702 703 |
# File 'lib/money/money.rb', line 701 def nonzero? cents != 0 ? self : nil end |
- (Money) remainder(val)
If different signs self.modulo(val) - val otherwise self.modulo(val)
660 661 662 663 664 665 666 667 668 669 670 |
# File 'lib/money/money.rb', line 660 def remainder(val) a, b = self, val b = b.exchange_to(a.currency) if b.is_a?(Money) and a.currency != b.currency a_sign, b_sign = :pos, :pos a_sign = :neg if a.cents < 0 b_sign = :neg if (b.is_a?(Money) and b.cents < 0) or (b < 0) return a.modulo(b) if a_sign == b_sign a.modulo(b) - (b.is_a?(Money) ? b : Money.new(b, a.currency)) end |
- (Array<Money, Money, Money>) split(num)
Split money amongst parties evenly without loosing pennies.
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 |
# File 'lib/money/money.rb', line 1046 def split(num) raise ArgumentError, "need at least one party" if num < 1 low = Money.new(cents / num) high = Money.new(low.cents + 1) remainder = cents % num result = [] num.times do |index| result[index] = index < remainder ? high : low end return result end |
- (String) symbol
Uses Currency#symbol. If nil is returned, defaults to “¤”.
711 712 713 |
# File 'lib/money/money.rb', line 711 def symbol currency.symbol || "¤" end |
- (Object) thousands_separator Also known as: delimiter
724 725 726 |
# File 'lib/money/money.rb', line 724 def thousands_separator currency.thousands_separator || "," 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.
941 942 943 |
# File 'lib/money/money.rb', line 941 def to_f (BigDecimal.new(cents.to_s) / currency.subunit_to_unit).to_f end |
- (self) to_money
Conversation to self.
998 999 1000 |
# File 'lib/money/money.rb', line 998 def to_money self end |
- (String) to_s
Returns the amount of money as a string.
921 922 923 924 925 926 927 928 929 930 |
# File 'lib/money/money.rb', line 921 def to_s unit, subunit = cents.abs.divmod(currency.subunit_to_unit).map{|o| o.to_s} if currency.decimal_places == 0 return "-#{unit}" if cents < 0 return unit end subunit = (("0" * currency.decimal_places) + subunit)[(-1*currency.decimal_places)..-1] return "-#{unit}#{decimal_mark}#{subunit}" if cents < 0 "#{unit}#{decimal_mark}#{subunit}" end |
- (Boolean) zero?
Test if the money amount is zero.
689 690 691 |
# File 'lib/money/money.rb', line 689 def zero? cents == 0 end |