Ивайло обнови решението на 16.01.2013 16:46 (преди около 12 години)
+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class ExchangeRate
+ class Unknown < RuntimeError
+ end
+
+ attr_reader :rates
+
+ def initialize()
+ @rates = {}
+ end
+
+ def set(first, second, rate)
+ @rates = @rates.merge({
+ first => { second => rate },
+ second => { first => BigDecimal.new('1')/rate },
+ })
+ end
+
+ def get(first, second)
+ return 1 if first == second
+ return @rates[first] && @rates[first][second]
+ end
+
+ def convert(first, second, amount)
+ rate = get(first, second)
+
+ if rate
+ rate * amount
+ else
+ raise Unknown
+ end
+ end
+end
+
+class Money
+ include Comparable
+ attr_reader :amount, :currency
+
+ def initialize(amount, currency)
+ @amount = amount
+ @currency = currency
+ end
+
+ def to_s()
+ "#{@amount.to_f.round(2)} #@currency"
+ end
+
+ def in(currency, exchange_rate)
+ Money.new exchange_rate.convert(@currency, currency, amount), currency
+ end
+
+ class IncompatibleCurrencies < StandardError
+ end
+
+ def compatible?(money)
+ if not money.is_a? Money
+ raise ArgumentError
+ elsif money.currency != self.currency
+ raise IncompatibleCurrencies
+ end
+ end
+
+ def *(amount)
+ Money.new @amount * amount.to_d, @currency
+ self
+ end
+
+ def /(amound)
+ Money.new @amount / amount.to_d, @currency
+ end
+
+ def +(money)
+ compatible?(money)
+ Money.new(self.amount + money.amount, @currency)
+ end
+
+ def -(money)
+ compatible?(money)
+ Money.new(self.amount + money.amount, @currency)
+ end
+
+ # def ==(money)
+ # compatible?(money)
+ # self.amount == money.amount
+ # end
+
+ # def !=(money)
+ # compatible?(money)
+ # self.amount != money.amount
+ # end
+
+ # def >(money)
+ # compatible?(money)
+ # self.amount > money.amount
+ # end
+
+ # def <(money)
+ # compatible?(money)
+ # self.amount < money.amount
+ # end
+
+ # def >=(money)
+ # compatible?(money)
+ # self.amount >= money.amount
+ # end
+
+ # def <=(money)
+ # compatible?(money)
+ # self.amount <= money.amount
+ # end
+
+ def <=>(money)
+ compatible?(money)
+ self.amount <=> money.amount
+ end
+end