lib/big_money/exchange.rb in shanna-big_money-0.2.2 vs lib/big_money/exchange.rb in shanna-big_money-0.3.0
- old
+ new
@@ -1,28 +1,65 @@
+# coding: utf-8
require 'bigdecimal'
class BigMoney
+ # == Synopsis
+ #
+ # require 'big_money'
+ # require 'big_money/exchange/yahoo' # Use yahoo finance exchange service.
+ #
+ # bm = BigMoney.new('3.99')
+ # bm.amount #=> BigDecimal.new('3.99')
+ # bm.currency #=> BigMoney::Currency::USD.instance
+ #
+ # bm2 = bm.exchange(:aud)
+ # bm.amount #=> BigDecimal.new('5.22')
+ # bm.currency #=> BigMoney::Currency::AUD.instance
+ module Exchangeable
+ # Exchange to a new Currency.
+ #
+ # ==== Examples
+ #
+ # BigMoney.new(12.50, :aud).exchange(:usd)
+ #
+ # ==== Parameters
+ # from<BigMoney::Currency, #to_s>:: Anything that BigMoney::Currency#find can find.
+ #
+ # ==== Returns
+ # BigMoney
+ def exchange(to)
+ ex = amount * Exchange.rate(currency, to)
+ self.class.new(ex, to)
+ end
+ end # Exchangeable
+ include Exchangeable
+
# Find the exchange rate between two currencies.
#
# Be aware no caching is done at all at the moment.
+ #--
+ # TODO: Moneta would be ideal for this.
class Exchange
- class ExchangeError < StandardError; end
- class ConversionError < ExchangeError; end
+ class ConversionError < StandardError; end
class << self
@@services = []
def inherited(service) #:nodoc:
@@services << service
end
- # Fetch the exchange rate between two currencies. The arguments may be anything that BigMoney::Currency can
- # parse. The rate is returned as a BigDecimal.
+ # Fetch the exchange rate between two currencies.
+ #
+ # ==== Parameters
+ # from<BigMoney::Currency, #to_s>:: Anything that BigMoney::Currency#find can find.
+ # to<BigMoney::Currency, #to_s>:: Anything that BigMoney::Currency#find can find.
+ #
+ # ==== Returns
+ # BigDecimal
def rate(from, to)
- exchange = [from, to].map do |c|
- Currency.parse(c) or raise BigMoney::UnknownCurrency
- end
+ exchange = [from, to].map{|c| Currency.find(c)}
return BigDecimal(1.to_s) if exchange.uniq.length == 1
service = @@services.reverse.find do |service|
!!exchange.reject{|c| service.currencies.include?(c)}
end
@@ -31,14 +68,30 @@
BigDecimal.new(service.read_rate(*exchange).to_s)
end
protected
# Exchange rate from the first currency to the second.
+ #
+ # ==== Notes
+ # Abstract.
+ #
+ # ==== Parameters
+ # from<BigMoney::Currency>::
+ # to<BigMoney::Currency>::
+ #
+ # ==== Returns
+ # BigDecimal
def read_rate(from, to)
raise NotImplementedError
end
- # An array of supported currencies.
+ # Supported currencies.
+ #
+ # ==== Notes
+ # Abstract.
+ #
+ # ==== Returns
+ # Array<BigMoney::Currency, #to_s>:: Anything that BigMoney::Currency#find can find.
def currencies
raise NotImplementedError
end
end
end # Exchange