Class: Money

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/money/money.rb,
lib/money/currency.rb,
lib/money/bank/base.rb,
lib/money/bank/variable_exchange.rb

Overview

Represents an amount of money in a given currency.

Defined Under Namespace

Modules: Bank, Formatter Classes: Currency

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(exact_number, currency = Money.default_currency, bank = Money.default_bank) ⇒ Money

Creates a new Money object of cents value in cents, with given currency.

Alternatively you can use the convenience methods like ca_dollar and us_dollar.

Examples:

Money.new(100)
#=> #<Money @cents=100 @currency="USD">
Money.new(100, "USD")
#=> #<Money @cents=100 @currency="USD">
Money.new(100, "EUR")
#=> #<Money @cents=100 @currency="EUR">

Parameters:

  • cents (Integer)

    The money amount, in cents.

  • currency (Currency, String, Symbol) (defaults to: Money.default_currency)

    The currency format.

  • bank (Money::Bank::*) (defaults to: Money.default_bank)

    The exchange bank to use.

See Also:



394
395
396
397
398
399
400
# File 'lib/money/money.rb', line 394

def initialize(exact_number, currency = Money.default_currency, bank = Money.default_bank)
  @exact_number = BigDecimal.new(exact_number.to_s)
  @cents = exact_number.round.to_i
  @currency = Currency.wrap(currency)
  @bank = bank
  @unit, @subunit  = @exact_number.to_f.abs.divmod(@currency.subunit_to_unit).map{|o| o.to_s}
end

Class Attribute Details

.default_bankMoney::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.

Returns:



37
38
39
# File 'lib/money/money.rb', line 37

def default_bank
  @default_bank
end

.default_currencyMoney::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.

Returns:



44
45
46
# File 'lib/money/money.rb', line 44

def default_currency
  @default_currency
end

Instance Attribute Details

#bankMoney::Bank::* (readonly)

The Money::Bank based object used to perform currency exchanges with.

Returns:



21
22
23
# File 'lib/money/money.rb', line 21

def bank
  @bank
end

#centsInteger (readonly)

The value of the money in cents.

Returns:

  • (Integer)


11
12
13
# File 'lib/money/money.rb', line 11

def cents
  @cents
end

#currencyCurrency (readonly)

The currency the money is in.

Returns:



16
17
18
# File 'lib/money/money.rb', line 16

def currency
  @currency
end

#exact_numberObject (readonly)

Returns the value of attribute exact_number.



23
24
25
# File 'lib/money/money.rb', line 23

def exact_number
  @exact_number
end

#subunitObject (readonly)

Returns the value of attribute subunit.



27
28
29
# File 'lib/money/money.rb', line 27

def subunit
  @subunit
end

#unitObject (readonly)

Returns the value of attribute unit.



25
26
27
# File 'lib/money/money.rb', line 25

def unit
  @unit
end

Class Method Details

.add_rate(from_currency, to_currency, rate) ⇒ Numeric

Adds a new exchange rate to the default bank and return the rate.

Examples:

Money.add_rate("USD", "CAD", 1.25) #=> 1.25

Parameters:

  • from_currency (Currency, String, Symbol)

    Currency to exchange from.

  • to_currency (Currency, String, Symbol)

    Currency to exchange to.

  • rate (Numeric)

    Rate to exchange with.

Returns:



367
368
369
# File 'lib/money/money.rb', line 367

def self.add_rate(from_currency, to_currency, rate)
  Money.default_bank.add_rate(from_currency, to_currency, rate)
end

.ca_dollar(cents) ⇒ Money

Creates a new Money object of the given value, using the Canadian dollar currency.

Examples:

n = Money.ca_dollar(100)
n.cents    #=> 100
n.currency #=> #<Money::Currency id: cad>

Parameters:

  • cents (Integer)

    The cents value.

Returns:



76
77
78
# File 'lib/money/money.rb', line 76

def self.ca_dollar(cents)
  Money.new(cents, "CAD")
end

.empty(currency = default_currency) ⇒ Money

Create a new money object with value 0.

Examples:

Money.empty #=> #<Money @cents=0>

Parameters:

  • currency (Currency, String, Symbol) (defaults to: default_currency)

    The currency to use.

Returns:



61
62
63
# File 'lib/money/money.rb', line 61

def self.empty(currency = default_currency)
  Money.new(0, currency)
end

.euro(cents) ⇒ Money

Creates a new Money object of the given value, using the Euro currency.

Examples:

n = Money.euro(100)
n.cents    #=> 100
n.currency #=> #<Money::Currency id: eur>

Parameters:

  • cents (Integer)

    The cents value.

Returns:



105
106
107
# File 'lib/money/money.rb', line 105

def self.euro(cents)
  Money.new(cents, "EUR")
end

.from_bigdecimal(value, currency = Money.default_currency) ⇒ Money

 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.

Examples:

Money.from_bigdecimal(BigDecimal.new("100")
#=> #<Money @cents=10000 @currency="USD">
Money.from_bigdecimal(BigDecimal.new("100", "USD")
#=> #<Money @cents=10000 @currency="USD">
Money.from_bigdecimal(BigDecimal.new("100", "EUR")
#=> #<Money @cents=10000 @currency="EUR">
Money.from_bigdecimal(BigDecimal.new("100", "BHD")
#=> #<Money @cents=100 @currency="BHD">

Parameters:

  • value (BigDecimal)

    The money amount, in dollars.

  • currency (Currency, String, Symbol) (defaults to: Money.default_currency)

    The currency format.

Returns:

See Also:



306
307
308
309
310
# File 'lib/money/money.rb', line 306

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

.from_fixnum(value, currency = Money.default_currency) ⇒ Money

 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.

Examples:

Money.from_fixnum(100)
#=> #<Money @cents=10000 @currency="USD">
Money.from_fixnum(100, "USD")
#=> #<Money @cents=10000 @currency="USD">
Money.from_fixnum(100, "EUR")
#=> #<Money @cents=10000 @currency="EUR">
Money.from_fixnum(100, "BHD")
#=> #<Money @cents=100 @currency="BHD">

Parameters:

  • value (Fixnum)

    The money amount, in dollars.

  • currency (Currency, String, Symbol) (defaults to: Money.default_currency)

    The currency format.

Returns:

See Also:



247
248
249
250
251
# File 'lib/money/money.rb', line 247

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

.from_float(value, currency = Money.default_currency) ⇒ Money

 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.

Examples:

Money.from_float(100.0)
#=> #<Money @cents=10000 @currency="USD">
Money.from_float(100.0, "USD")
#=> #<Money @cents=10000 @currency="USD">
Money.from_float(100.0, "EUR")
#=> #<Money @cents=10000 @currency="EUR">
Money.from_float(100.0, "BHD")
#=> #<Money @cents=100 @currency="BHD">

Parameters:

  • value (Float)

    The money amount, in dollars.

  • currency (Currency, String, Symbol) (defaults to: Money.default_currency)

    The currency format.

Returns:

See Also:



279
280
281
# File 'lib/money/money.rb', line 279

def self.from_float(value, currency = Money.default_currency)
  from_bigdecimal(BigDecimal.new(value.to_s), currency)
end

.from_numeric(value, currency = Money.default_currency) ⇒ Money

 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.

Examples:

Money.from_numeric(100)
#=> #<Money @cents=10000 @currency="USD">
Money.from_numeric(100.00)
#=> #<Money @cents=10000 @currency="USD">
Money.from_numeric("100")
#=> ArgumentError

Parameters:

  • value (Numeric)

    The money amount, in dollars.

  • currency (Currency, String, Symbol) (defaults to: Money.default_currency)

    The currency format.

Returns:

Raises:

  • ArgumentError Unless value is a supported type.

See Also:



345
346
347
348
349
350
351
352
353
354
# File 'lib/money/money.rb', line 345

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

.from_string(value, currency = Money.default_currency) ⇒ Money

 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.

Examples:

Money.from_string("100")
#=> #<Money @cents=10000 @currency="USD">
Money.from_string("100", "USD")
#=> #<Money @cents=10000 @currency="USD">
Money.from_string("100", "EUR")
#=> #<Money @cents=10000 @currency="EUR">
Money.from_string("100", "BHD")
#=> #<Money @cents=100 @currency="BHD">

Parameters:

  • value (String, #to_s)

    The money amount, in dollars.

  • currency (Currency, String, Symbol) (defaults to: Money.default_currency)

    The currency to set the resulting Money object to.

Returns:

See Also:



220
221
222
# File 'lib/money/money.rb', line 220

def self.from_string(value, currency = Money.default_currency)
  from_bigdecimal(BigDecimal.new(value.to_s), currency)
end

.new_with_dollars(amount, currency = Money.default_currency, bank = Money.default_bank) ⇒ Money

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.

Examples:

Money.new_with_dollars(100)
#=> #<Money @cents=10000 @currency="USD">
Money.new_with_dollars(100, "USD")
#=> #<Money @cents=10000 @currency="USD">
Money.new_with_dollars(100, "EUR")
#=> #<Money @cents=10000 @currency="EUR">

Parameters:

  • amount (Numeric)

    The money amount, in dollars.

  • currency (Currency, String, Symbol) (defaults to: Money.default_currency)

    The currency format.

  • bank (Money::Bank::*) (defaults to: Money.default_bank)

    The exchange bank to use.

Returns:

See Also:

  • new


134
135
136
137
138
139
# File 'lib/money/money.rb', line 134

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

.parse(input, currency = nil) ⇒ Money

Parses the current string and converts it to a Money object. Excess characters will be discarded.

Examples:

'100'.to_money                #=> #<Money @cents=10000>
'100.37'.to_money             #=> #<Money @cents=10037>
'100 USD'.to_money            #=> #<Money @cents=10000, @currency=#<Money::Currency id: usd>>
'USD 100'.to_money            #=> #<Money @cents=10000, @currency=#<Money::Currency id: usd>>
'$100 USD'.to_money           #=> #<Money @cents=10000, @currency=#<Money::Currency id: usd>>
'hello 2000 world'.to_money   #=> #<Money @cents=200000 @currency=#<Money::Currency id: usd>>

Mismatching currencies

'USD 2000'.to_money("EUR")    #=> ArgumentError

Parameters:

  • input (String, #to_s)

    The input to parse.

  • currency (Currency, String, Symbol) (defaults to: nil)

    The currency format. The currency to set the resulting Money object to.

Returns:

Raises:

  • (ArgumentError)

    If any currency is supplied and given value doesn’t match the one extracted from the input string.

See Also:



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/money/money.rb', line 168

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

.us_dollar(cents) ⇒ Money

Creates a new Money object of the given value, using the American dollar currency.

Examples:

n = Money.us_dollar(100)
n.cents    #=> 100
n.currency #=> #<Money::Currency id: usd>

Parameters:

  • cents (Integer)

    The cents value.

Returns:



91
92
93
# File 'lib/money/money.rb', line 91

def self.us_dollar(cents)
  Money.new(cents, "USD")
end

Instance Method Details

#%(val) ⇒ Money

Synonym for #modulo.

Parameters:

  • val (Money, Fixnum)

    Number take modulo with.

Returns:

See Also:



656
657
658
# File 'lib/money/money.rb', line 656

def %(val)
  self.modulo(val)
end

#*(value) ⇒ Money

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.

Examples:

Money.new(100) * 2 #=> #<Money @cents=200>

Parameters:

  • value (Numeric)

    Number to multiply by.

Returns:

  • (Money)

    The resulting money.

Raises:

  • (ArgumentError)

    If value is a Money instance.



567
568
569
570
571
572
573
# File 'lib/money/money.rb', line 567

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

#+(other_money) ⇒ 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.

Examples:

Money.new(100) + Money.new(100) #=> #<Money @cents=200>

Parameters:

  • other_money (Money)

    Other Money object to add.

Returns:



526
527
528
529
530
531
532
# File 'lib/money/money.rb', line 526

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

#-(other_money) ⇒ 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.

Examples:

Money.new(100) - Money.new(99) #=> #<Money @cents=1>

Parameters:

  • other_money (Money)

    Other Money object to subtract.

Returns:



545
546
547
548
549
550
551
# File 'lib/money/money.rb', line 545

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

#/(value) ⇒ Money, Float

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.

Examples:

Money.new(100) / 10            #=> #<Money @cents=10>
Money.new(100) / Money.new(10) #=> 10.0

Parameters:

Returns:

  • (Money)

    The resulting money if you divide Money by a number.

  • (Float)

    The resulting number if you divide Money by a Money.



590
591
592
593
594
595
596
597
598
599
600
# File 'lib/money/money.rb', line 590

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

#<=>(other_money) ⇒ -1, ...

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.

Examples:

Money.new(100) <=> 99             #=>  1
Money.new(100) <=> Money.new(100) #=>  0
Money.new(100) <=> "$101.00"      #=> -1

Parameters:

Returns:

  • (-1, 0, 1)

Raises:

  • (ArgumentError)


503
504
505
506
507
508
509
510
511
512
513
514
# File 'lib/money/money.rb', line 503

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

#==(other_money) ⇒ Boolean

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.

Examples:

Money.new(100) == Money.new(101) #=> false
Money.new(100) == Money.new(100) #=> true

Parameters:

  • other_money (Money)

    Value to compare with.

Returns:

  • (Boolean)


451
452
453
454
455
456
457
458
# File 'lib/money/money.rb', line 451

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

#absMoney

Return absolute value of self as a new Money object.

Examples:

Money.new(-100).abs #=> #<Money @cents=100>

Returns:



686
687
688
# File 'lib/money/money.rb', line 686

def abs
  Money.new(self.cents.abs, self.currency)
end

#allocate(splits) ⇒ Array<Money, Money, Money>

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

Examples:

Money.new(5, "USD").allocate([0.3,0.7)) #=> [Money.new(2), Money.new(3)]
Money.new(100, "USD").allocate([0.33,0.33,0.33]) #=> [Money.new(34), Money.new(33), Money.new(33)]

Parameters:

  • to (0.50, 0.25, 0.25)

    give 50% of the cash to party1, 25% ot party2, and 25% to party3.

Returns:

Raises:

  • (ArgumentError)


1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
# File 'lib/money/money.rb', line 1052

def allocate(splits)
  allocations = splits.inject(0.0) {|sum, i| sum += i }
  raise ArgumentError, "splits add to more then 100%" if allocations > 1.0

  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

#as_ca_dollarMoney

Receive a money object with the same amount as the current Money object in canadian dollar.

Examples:

n = Money.new(100, "USD").as_ca_dollar
n.currency #=> #<Money::Currency id: cad>

Returns:



1010
1011
1012
# File 'lib/money/money.rb', line 1010

def as_ca_dollar
  exchange_to("CAD")
end

#as_euroMoney

Receive a money object with the same amount as the current Money object in euro.

Examples:

n = Money.new(100, "USD").as_euro
n.currency #=> #<Money::Currency id: eur>

Returns:



1022
1023
1024
# File 'lib/money/money.rb', line 1022

def as_euro
  exchange_to("EUR")
end

#as_us_dollarMoney

Receive a money object with the same amount as the current Money object in american dollars.

Examples:

n = Money.new(100, "CAD").as_us_dollar
n.currency #=> #<Money::Currency id: usd>

Returns:



998
999
1000
# File 'lib/money/money.rb', line 998

def as_us_dollar
  exchange_to("USD")
end

#currency_as_stringString

Return string representation of currency object

Examples:

Money.new(100, :USD).currency_as_string #=> "USD"

Returns:



424
425
426
# File 'lib/money/money.rb', line 424

def currency_as_string
  self.currency.to_s
end

#currency_as_string=(val) ⇒ Money::Currency

Set currency object using a string

Examples:

Money.new(100).currency_as_string("CAD") #=> #<Money::Currency id: cad>

Parameters:

  • val (String)

    The currency string.

Returns:



436
437
438
# File 'lib/money/money.rb', line 436

def currency_as_string=(val)
  @currency = Currency.wrap(val)
end

#decimal_markObject Also known as: separator



751
752
753
# File 'lib/money/money.rb', line 751

def decimal_mark
  I18n.t(:"number.format.decimal_mark", :default => currency.decimal_mark || ".")
end

#div(value) ⇒ Money, Float

Synonym for #/.

Parameters:

Returns:

  • (Money)

    The resulting money if you divide Money by a number.

  • (Float)

    The resulting number if you divide Money by a Money.

See Also:



611
612
613
# File 'lib/money/money.rb', line 611

def div(value)
  self / value
end

#divmod(val) ⇒ Array<Money,Money>, Array<Fixnum,Money>

Divide money by money or fixnum and return array containing quotient and modulus.

Examples:

Money.new(100).divmod(9)            #=> [#<Money @cents=11>, #<Money @cents=1>]
Money.new(100).divmod(Money.new(9)) #=> [11, #<Money @cents=1>]

Parameters:

  • val (Money, Fixnum)

    Number to divmod by.

Returns:



625
626
627
628
629
630
631
632
633
634
# File 'lib/money/money.rb', line 625

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

#dollarsFloat

Returns the value of the money in dollars, instead of in cents.

Examples:

Money.new(100).dollars           # => 1.0
Money.new_with_dollars(1).dollar # => 1.0

Returns:

  • (Float)

See Also:



414
415
416
# File 'lib/money/money.rb', line 414

def dollars
  to_f
end

#eql?(other_money) ⇒ Money

Synonymous with #==.

Parameters:

  • other_money (Money)

    Value to compare with.

Returns:

See Also:



467
468
469
# File 'lib/money/money.rb', line 467

def eql?(other_money)
  self == other_money
end

#exchange_to(other_currency) ⇒ Money

Receive the amount of this money object in another Currency.

Examples:

Money.new(2000, "USD").exchange_to("EUR")
Money.new(2000, "USD").exchange_to(Currency.new("EUR"))

Parameters:

  • other_currency (Currency, String, Symbol)

    Currency to exchange to.

Returns:



985
986
987
988
# File 'lib/money/money.rb', line 985

def exchange_to(other_currency)
  other_currency = Currency.wrap(other_currency)
  @bank.exchange_with(self, other_currency)
end

#format(*rules) ⇒ Object



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
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
# File 'lib/money/money.rb', line 855

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
  if rules[:decimals] && !rules[:no_cents]
    formatted = formatted + exact_number.to_f.to_s.split('.')[1]
  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

  d_mark = decimal_mark

  if rules.has_key?(:decimal_mark) and rules[:decimal_mark] and
    rules[:decimal_mark] != decimal_mark
    formatted.sub!(decimal_mark, rules[:decimal_mark])
    d_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
  if (rules.has_key?(:decimal_mark) and rules[:decimal_mark]) or rules[:decimals]
    decimals = rules[:decimals] || 2
    integer, rational = formatted.split(d_mark)
    rational, symbol = rational.split
    integer.gsub!(/(\d)(?=(?:\d{3})+(?:[^\d]|$))/, "\\1#{thousands_separator_value}")
    rational_slice = rational.slice(0, decimals) 
    (decimals - rational_slice.length).times { rational_slice << '0' }
    formatted = (integer + d_mark + rational_slice + " #{symbol}").strip
  else
    formatted.gsub!(/(\d)(?=(?:\d{3})+(?:[^\d]|$))/, "\\1#{thousands_separator_value}")
  end


  if rules[:with_currency]
    formatted << " "
    formatted << '<span class="currency">' if rules[:html]
    formatted << currency.to_s
    formatted << '</span>' if rules[:html]
  end
  formatted
end

#hashFixnum

Returns a Fixnum hash value based on the cents and currency attributes in order to use functions like & (intersection), group_by, etc.

Examples:

Money.new(100).hash #=> 908351

Returns:

  • (Fixnum)


478
479
480
# File 'lib/money/money.rb', line 478

def hash
  [cents.hash, currency.hash].hash
end

#huhString

Creates a formatted price string according to several rules.

Examples:

Money.us_dollar(0).format(:display_free => true)     #=> "free"
Money.us_dollar(0).format(:display_free => "gratis") #=> "gratis"
Money.us_dollar(0).format                            #=> "$0.00"
Money.ca_dollar(100).format => "$1.00"
Money.ca_dollar(100).format(:with_currency => true) #=> "$1.00 CAD"
Money.us_dollar(85).format(:with_currency => true)  #=> "$0.85 USD"
Money.ca_dollar(100).format(:no_cents => true) #=> "$1"
Money.ca_dollar(599).format(:no_cents => true) #=> "$5"
Money.new(100, "USD") #=> "$1.00"
Money.new(100, "GBP") #=> "£1.00"
Money.new(100, "EUR") #=> "€1.00"

# Same thing.
Money.new(100, "USD").format(:symbol => true) #=> "$1.00"
Money.new(100, "GBP").format(:symbol => true) #=> "£1.00"
Money.new(100, "EUR").format(:symbol => true) #=> "€1.00"

# You can specify a false expression or an empty string to disable
# prepending a money symbol.
Money.new(100, "USD").format(:symbol => false) #=> "1.00"
Money.new(100, "GBP").format(:symbol => nil)   #=> "1.00"
Money.new(100, "EUR").format(:symbol => "")    #=> "1.00"

# If the symbol for the given currency isn't known, then it will default
# to "¤" as symbol.
Money.new(100, "AWG").format(:symbol => true) #=> "¤1.00"

# You can specify a string as value to enforce using a particular symbol.
Money.new(100, "AWG").format(:symbol => "ƒ") #=> "ƒ1.00"
# If a string is specified, it's value is used.
Money.new(100, "USD").format(:decimal_mark => ",") #=> "$1,00"

# If the decimal_mark for a given currency isn't known, then it will default
# to "." as decimal_mark.
Money.new(100, "FOO").format #=> "$1.00"
# If false is specified, no thousands_separator is used.
Money.new(100000, "USD").format(:thousands_separator => false) #=> "1000.00"
Money.new(100000, "USD").format(:thousands_separator => nil)   #=> "1000.00"
Money.new(100000, "USD").format(:thousands_separator => "")    #=> "1000.00"

# If a string is specified, it's value is used.
Money.new(100000, "USD").format(:thousands_separator => ".") #=> "$1.000.00"

# If the thousands_separator for a given currency isn't known, then it will
# default to "," as thousands_separator.
Money.new(100000, "FOO").format #=> "$1,000.00"
s = Money.ca_dollar(570).format(:html => true, :with_currency => true)
s #=>  "$5.70 <span class=\"currency\">CAD</span>"

Parameters:

  • *rules (Hash)

    The options used to format the string.

Returns:



849
850
851
852
853
# File 'lib/money/money.rb', line 849

def huh
  rules = normalize_formatting_rules(rules)
  puts rules.inspect
  Money::Formatter::CurrencyName.new(:previous => self, :formatted_string => self.cents.to_s, :rules => rules).format
end

#inspectString

Common inspect function

Returns:



1036
1037
1038
# File 'lib/money/money.rb', line 1036

def inspect
  "#<Money cents:#{cents} currency:#{currency}>"
end

#modulo(val) ⇒ Money

Equivalent to self.divmod(val)

Examples:

Money.new(100).modulo(9)            #=> #<Money @cents=1>
Money.new(100).modulo(Money.new(9)) #=> #<Money @cents=1>

Parameters:

  • val (Money, Fixnum)

    Number take modulo with.

Returns:



645
646
647
# File 'lib/money/money.rb', line 645

def modulo(val)
  self.divmod(val)[1]
end

#nonzero?Money?

Test if the money amount is non-zero. Returns this money object if it is non-zero, or nil otherwise, like Numeric#nonzero?.

Examples:

Money.new(100).nonzero? #=> #<Money @cents=100>
Money.new(0).nonzero?   #=> nil

Returns:



709
710
711
# File 'lib/money/money.rb', line 709

def nonzero?
  cents != 0 ? self : nil
end

#remainder(val) ⇒ Money

If different signs self.modulo(val) - val otherwise self.modulo(val)

Examples:

Money.new(100).remainder(9) #=> #<Money @cents=1>

Parameters:

  • val (Money, Fixnum)

    Number to rake remainder with.

Returns:



668
669
670
671
672
673
674
675
676
677
678
# File 'lib/money/money.rb', line 668

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

#split(num) ⇒ Array<Money, Money, Money>

Split money amongst parties evenly without loosing pennies.

Examples:

Money.new(100, "USD").split(3) #=> [Money.new(34), Money.new(33), Money.new(33)]

Parameters:

  • number (2)

    of parties.

Returns:

Raises:

  • (ArgumentError)


1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
# File 'lib/money/money.rb', line 1077

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

#symbolString

Uses Currency#symbol. If nil is returned, defaults to “¤”.

Examples:

Money.new(100, "USD").symbol #=> "$"

Returns:



719
720
721
# File 'lib/money/money.rb', line 719

def symbol
  currency.symbol || "¤"
end

#thousands_separatorObject Also known as: delimiter



732
733
734
# File 'lib/money/money.rb', line 732

def thousands_separator
  I18n.t(:"number.format.thousands_separator", :default => currency.thousands_separator || ",")
end

#to_fFloat

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.

Examples:

Money.us_dollar(100).to_f => 1.0

Returns:

  • (Float)


972
973
974
# File 'lib/money/money.rb', line 972

def to_f
  (BigDecimal.new(cents.to_s) / currency.subunit_to_unit).to_f
end

#to_moneyself

Conversation to self.

Returns:

  • (self)


1029
1030
1031
# File 'lib/money/money.rb', line 1029

def to_money
  self
end

#to_sString

Returns the amount of money as a string.

Examples:

Money.ca_dollar(100).to_s #=> "1.00"

Returns:



952
953
954
955
956
957
958
959
960
961
# File 'lib/money/money.rb', line 952

def to_s
  if currency.decimal_places == 0
    return "-#{@unit}" if exact_number.to_f < 0
    return @unit
  end
  subunit = (("0" * currency.decimal_places) + @subunit.to_i.to_s)[(-1*currency.decimal_places)..-1]

  return "-#{@unit}#{decimal_mark}#{subunit}" if exact_number.to_f < 0
  "#{@unit}#{decimal_mark}#{subunit}"
end

#zero?Boolean

Test if the money amount is zero.

Examples:

Money.new(100).zero? #=> false
Money.new(0).zero?   #=> true

Returns:

  • (Boolean)


697
698
699
# File 'lib/money/money.rb', line 697

def zero?
  cents == 0
end