$5 + 10 CHF = $10 if rate is 2:1
$5 * 2 - $10
Make "amount" private
Dollar side effects?
Money rounding?
equals()
hashCode()
Equal null
Equal object
public void testMultiplication {
Dollar five = new Dollar(5);
assertEquals(new Dollar(10), five.times(2));
assertEquals(new Dollar(15), five.times(3));
}
require 'test/unit'
require 'dollar.rb'
class TestDollar < Test::Unit::TestCase
def test_multiplication
five = Dollar.new(5)
assert_equal(five.times(2), Dollar.new(10))
assert_equal(five.times(3), Dollar.new(15))
end
def test_equality
assert_equal(Dollar.new(5), Dollar.new(5))
assert_not_equal(Dollar.new(5), Dollar.new(6))
end
end
require 'spec'
require 'dollar.rb'
class DollarSpecification < Spec::Context
def multiplication
five = Dollar.new(5)
five.times(2).should.equal Dollar.new(10)
five.times(3).should.equal Dollar.new(15)
end
def equality
Dollar.new(5).should.equal Dollar.new(5)
Dollar.new(5).should.not.equal Dollar.new(6)
end
end
class Dollar
attr_reader :amount
def initialize(amount)
@amount = amount
end
def times(multiplier)
Dollar.new(@amount * multiplier)
end
def eql?(object)
self == (object)
end
def ==(object)
object.equal?(self) ||
(object.instance_of?(self.class) && object.amount == @amount)
end
end
The interesting part is how to handle equality properly. In the previous chapter, I mistakenly thought equals() was an arbitrary method that Kent Beck came up with, but in fact it's part of the Java Core API. The equivalent in Ruby is (). However, when I overloaded (), it was apparent that a simple object.amount == @amount was not the proper way to compare objects. After searching and asking questions in #ruby-lang, I found the "right way" to implment ==()/equals() on Simon Harris' blog entry on How To Write eql?() in Ruby.