Виктория обнови решението на 15.01.2013 18:16 (преди около 12 години)
+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class ExchangeRate
+ attr_accessor :rates #hash
+
+ def initialize()
+ @rates = {}
+ end
+
+class Unknown < RuntimeError
+end
+
+ def set(from_currency, to_currency, rate)
+ unless from_currency == to_currency
+ rates[[from_currency, to_currency]] = rate
+ rates[[to_currency, from_currency]] = (1.0/rate).to_d
+ end
+ end
+
+ def get(from_currency, to_currency)
+ from_currency == to_currency ? '1'.to_d : rates[[from_currency, to_currency]]
+ end
+
+ def convert(from_currency, to_currency, amount)
+ raise Unknown if rates[[from_currency, to_currency]] == nil
+ from_currency == to_currency ? amount : amount * rates[[from_currency, to_currency]]
+ end
+end
+
+class Money
+ include Comparable
+
+ attr_accessor :amount, :currency
+
+ def initialize(amount, currency)
+ @amount = amount
+ @currency = currency
+ end
+
+ class IncompatibleCurrencies < RuntimeError
+ end
+
+ def to_s
+ amount.truncate(2).to_s('F') + ' ' + currency.to_s
+ end
+
+ def in(to_currency, exchange_rate)
+ raise ExchangeRate::Unknown unless exchange_rate.get(currency, to_currency)
+ Money.new(exchange_rate.convert(currency, to_currency, amount), to_currency)
+ end
+
+ def is_same_currency?(money)
+ raise ArgumentError unless money.class == Money
+ raise IncompatibleCurrencies unless currency == money.currency
+ end
+
+ def <=>(money)
+ is_same_currency?(money)
+ amount <=> money.amount
+ end
+
+ def +(money)
+ is_same_currency?(money)
+ Money.new amount + money.amount, currency
+ end
+
+ def -(money)
+ is_same_currency?(money)
+ Money.new amount - money.amount, currency
+ end
+
+ def *(number)
+ raise ArgumentError unless number.kind_of? Numeric
+ Money.new number * amount, currency
+ end
+
+ def /(number)
+ raise ArgumentError unless number.kind_of? Numeric
+ Money.new amount / number, currency
+ end
+end