Class: Money
Defined Under Namespace
Classes: MoneyError
Constant Summary collapse
- @@bank =
Bank lets you exchange the object which is responsible for currency exchange. The default implementation just throws an exception. However money ships with a variable exchange bank implementation which supports custom excahnge rates:
Money.bank = VariableExchangeBank.new Money.bank.add_rate("USD", "CAD", 1.24515) Money.bank.add_rate("CAD", "USD", 0.803115) Money.us_dollar(100).exchange_to("CAD") => Money.ca_dollar(124) Money.ca_dollar(100).exchange_to("USD") => Money.us_dollar(80) NoExchangeBank.new
- @@default_currency =
"USD"
Instance Attribute Summary collapse
-
#cents ⇒ Object
readonly
Returns the value of attribute cents.
-
#currency ⇒ Object
readonly
Returns the value of attribute currency.
-
#precision ⇒ Object
readonly
Returns the value of attribute precision.
Class Method Summary collapse
-
.ca_dollar(num) ⇒ Object
Create a new money object using the Canadian dollar currency.
-
.empty(currency = default_currency) ⇒ Object
Create a new money object with value 0.
-
.euro(num) ⇒ Object
Create a new money object using the Euro currency.
-
.us_dollar(num) ⇒ Object
Create a new money object using the American dollar currency.
Instance Method Summary collapse
-
#*(fixnum) ⇒ Object
multiply money by fixnum.
- #+(other_money) ⇒ Object
- #-(other_money) ⇒ Object
- #-@ ⇒ Object
-
#/(fixnum) ⇒ Object
divide money by fixnum.
- #<=>(other_money) ⇒ Object
-
#as_ca_dollar ⇒ Object
Recieve a money object with the same amount as the current Money object in canadian dollar.
-
#as_ca_euro ⇒ Object
Recieve a money object with the same amount as the current Money object in euro.
-
#as_us_dollar ⇒ Object
Recieve a money object with the same amount as the current Money object in american dollar.
-
#eql?(other_money) ⇒ Boolean
Do two money objects equal? Only works if both objects are of the same currency.
-
#exchange_to(other_currency) ⇒ Object
Recieve the amount of this money object in another currency.
-
#format(*rules) ⇒ Object
Format the price according to several rules Currently supported are :with_currency, :no_cents and :html.
-
#initialize(cents, currency = default_currency, precision = 2) ⇒ Money
constructor
Creates a new money object.
- #separator ⇒ Object
- #to_chart(*rules) ⇒ Object
- #to_f ⇒ Object
- #to_format(show_precision = precision) ⇒ Object
-
#to_money(precision = nil) ⇒ Object
Conversation to self.
- #to_precision(new_precision) ⇒ Object
-
#to_s(show_precision = precision) ⇒ Object
Money.ca_dollar(100).to_s => “1.00”.
-
#zero? ⇒ Boolean
Test if the money amount is zero.
Constructor Details
#initialize(cents, currency = default_currency, precision = 2) ⇒ Money
Creates a new money object.
Money.new(100)
Alternativly you can use the convinience methods like Money.ca_dollar and Money.us_dollar
39 40 41 |
# File 'lib/money.rb', line 39 def initialize(cents, currency = default_currency, precision = 2) @cents, @currency, @precision = cents.round, currency, precision end |
Instance Attribute Details
#cents ⇒ Object (readonly)
Returns the value of attribute cents.
9 10 11 |
# File 'lib/money.rb', line 9 def cents @cents end |
#currency ⇒ Object (readonly)
Returns the value of attribute currency.
9 10 11 |
# File 'lib/money.rb', line 9 def currency @currency end |
#precision ⇒ Object (readonly)
Returns the value of attribute precision.
9 10 11 |
# File 'lib/money.rb', line 9 def precision @precision end |
Class Method Details
.ca_dollar(num) ⇒ Object
Create a new money object using the Canadian dollar currency
218 219 220 |
# File 'lib/money.rb', line 218 def self.ca_dollar(num) Money.new(num, "CAD") end |
.empty(currency = default_currency) ⇒ Object
Create a new money object with value 0
213 214 215 |
# File 'lib/money.rb', line 213 def self.empty(currency = default_currency) Money.new(0, currency) end |
.euro(num) ⇒ Object
Create a new money object using the Euro currency
228 229 230 |
# File 'lib/money.rb', line 228 def self.euro(num) Money.new(num, "EUR") end |
.us_dollar(num) ⇒ Object
Create a new money object using the American dollar currency
223 224 225 |
# File 'lib/money.rb', line 223 def self.us_dollar(num) Money.new(num, "USD") end |
Instance Method Details
#*(fixnum) ⇒ Object
multiply money by fixnum
75 76 77 |
# File 'lib/money.rb', line 75 def *(fixnum) Money.new(cents * fixnum, currency, precision) end |
#+(other_money) ⇒ Object
56 57 58 59 60 61 |
# File 'lib/money.rb', line 56 def +(other_money) other_money = other_money.exchange_to(currency) unless other_money.currency == currency new_precision = [precision, other_money.precision].max Money.new(to_precision(new_precision).cents + other_money.to_precision(new_precision).cents, currency, new_precision) end |
#-(other_money) ⇒ Object
63 64 65 66 67 68 |
# File 'lib/money.rb', line 63 def -(other_money) other_money = other_money.exchange_to(currency) unless other_money.currency == currency new_precision = [precision, other_money.precision].max Money.new(to_precision(new_precision).cents - other_money.to_precision(new_precision).cents, currency, new_precision) end |
#-@ ⇒ Object
70 71 72 |
# File 'lib/money.rb', line 70 def -@ Money.new(-cents, currency, precision) end |
#/(fixnum) ⇒ Object
divide money by fixnum
80 81 82 |
# File 'lib/money.rb', line 80 def /(fixnum) Money.new(cents / fixnum, currency, precision) end |
#<=>(other_money) ⇒ Object
48 49 50 51 52 53 54 |
# File 'lib/money.rb', line 48 def <=>(other_money) if currency == other_money.currency cents <=> other_money.cents else cents <=> other_money.exchange_to(currency).cents end end |
#as_ca_dollar ⇒ Object
Recieve a money object with the same amount as the current Money object in canadian dollar
240 241 242 |
# File 'lib/money.rb', line 240 def as_ca_dollar exchange_to("CAD") end |
#as_ca_euro ⇒ Object
Recieve a money object with the same amount as the current Money object in euro
246 247 248 |
# File 'lib/money.rb', line 246 def as_ca_euro exchange_to("EUR") end |
#as_us_dollar ⇒ Object
Recieve a money object with the same amount as the current Money object in american dollar
234 235 236 |
# File 'lib/money.rb', line 234 def as_us_dollar exchange_to("USD") end |
#eql?(other_money) ⇒ Boolean
Do two money objects equal? Only works if both objects are of the same currency
44 45 46 |
# File 'lib/money.rb', line 44 def eql?(other_money) cents == other_money.cents && currency == other_money.currency end |
#exchange_to(other_currency) ⇒ Object
Recieve the amount of this money object in another currency
202 203 204 |
# File 'lib/money.rb', line 202 def exchange_to(other_currency) self.class.bank.exchange(self, other_currency) end |
#format(*rules) ⇒ Object
Format the price according to several rules Currently supported are :with_currency, :no_cents and :html
with_currency:
Money.ca_dollar(0).format => "free"
Money.ca_dollar(100).format => "$1.00"
Money.ca_dollar(100).format(:with_currency) => "$1.00 CAD"
Money.us_dollar(85).format(:with_currency) => "$0.85 USD"
no_cents:
Money.ca_dollar(100).format(:no_cents) => "$1"
Money.ca_dollar(599).format(:no_cents) => "$5"
Money.ca_dollar(570).format(:no_cents, :with_currency) => "$5 CAD"
Money.ca_dollar(39000).format(:no_cents) => "$390"
html:
Money.ca_dollar(570).format(:html, :with_currency) => "$5.70 <span class=\"currency\">CAD</span>"
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/money.rb', line 111 def format(*rules) return self.class.zero if zero? && self.class.zero euro_symbol = [8364].pack("U") rules = rules.flatten case self.currency when 'EUR' formatted = to_format(rules.include?(:no_cents) ? 0 : 2) +"#{euro_symbol}" when 'GBP' formatted = "\u00A3" + to_format(rules.include?(:no_cents) ? 0 : 2) when 'USD' formatted = "$" + to_format(rules.include?(:no_cents) ? 0 : 2) when 'CAD' formatted = "$" + to_format(rules.include?(:no_cents) ? 0 : 2) else formatted = "$" + to_format(rules.include?(:no_cents) ? 0 : 2) end if rules.include?(:with_currency) formatted << " " formatted << '<span class="currency">' if rules.include?(:html) formatted << currency formatted << '</span>' if rules.include?(:html) end formatted end |
#separator ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/money.rb', line 182 def separator case self.currency when 'EUR' ',' when 'GBP' ',' when 'USD' '.' when 'CAD' '.' else '.' end end |
#to_chart(*rules) ⇒ Object
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/money.rb', line 165 def to_chart(*rules) rules = rules.flatten case self.currency when 'EUR' formatted = to_s(rules.include?(:no_cents) ? 0 : 2) +"€" when 'GBP' formatted = "£" + to_s(rules.include?(:no_cents) ? 0 : 2) when 'USD' formatted = "$" + to_s(rules.include?(:no_cents) ? 0 : 2) when 'CAD' formatted = "$" + to_s(rules.include?(:no_cents) ? 0 : 2) else formatted = "$" + to_s(rules.include?(:no_cents) ? 0 : 2) end formatted end |
#to_f ⇒ Object
197 198 199 |
# File 'lib/money.rb', line 197 def to_f cents.to_f / 10 ** precision end |
#to_format(show_precision = precision) ⇒ Object
157 158 159 160 161 162 163 |
# File 'lib/money.rb', line 157 def to_format(show_precision = precision) if show_precision > 0 sprintf("%.#{show_precision}f", to_f ).gsub('.', separator) else sprintf("%d", cents.to_f / 10 ** (precision - show_precision) ).gsub('.', separator) end end |
#to_money(precision = nil) ⇒ Object
Conversation to self
251 252 253 |
# File 'lib/money.rb', line 251 def to_money(precision = nil) precision ? to_precision(precision) : self end |
#to_precision(new_precision) ⇒ Object
206 207 208 209 210 |
# File 'lib/money.rb', line 206 def to_precision(new_precision) difference = new_precision - precision new_cents = difference > 0 ? cents * 10**difference : (cents.to_f / 10**difference.abs).round Money.new(new_cents, currency, new_precision) end |
#to_s(show_precision = precision) ⇒ Object
Money.ca_dollar(100).to_s => “1.00”
Locale support:
If
number.currency.separator = ","
number.currency.separator = "."
Then
Money.ca_dollar(100).to_s => "1,00"
148 149 150 151 152 153 154 155 |
# File 'lib/money.rb', line 148 def to_s(show_precision = precision) s_separator = I18n.translate("number.format.separator", :default => ".") if show_precision > 0 sprintf("%.#{show_precision}f", to_f ).gsub('.', s_separator) else sprintf("%d", cents.to_f / 10 ** (precision - show_precision) ).gsub('.', s_separator) end end |
#zero? ⇒ Boolean
Test if the money amount is zero
85 86 87 |
# File 'lib/money.rb', line 85 def zero? cents == 0 end |