One of the most important kind of values in computing is Money.
Money is an arithmetic object because you can add money, multiply
money times numbers, and even divide one money times another to
get a percent. Money can be complicated because it is always
expressed in a particular curency, and you have to convert from
one currency to another before you can add or subtract amounts
of money. However, we will leave conversion to another time and
just worry about making it act like an arithmetic object today.
Each Money object knows its currency. Arithmetic operations must
check to make sure that currencies match. When you print out
a Money value, it will always display its currency. You specify
how an object prints out by defining printOn:..
Not all combinations of arithmetic operations work.
Money * Number = Money
Money * Money :: ERROR
Money + Money = Money
Money + Number :: ERROR
Money - Money = Money
Money - Number :: ERROR
Money / Money = Number
Money / Number = Money
Number / Money :: ERROR
A money object has a currency and a magnitude. The currency could
be a string giving the name of the currency or an instance of
a Currency class. Eventually we'll probably need a Currency class,
but it is easiest to use a string just now. The magnitude needs
to be a FixedPoint. (Read the comment for FixedPoint.)
There are two ways to make a Money object. One is
Money currency: 'US dollar' magnitude: 3.45
Another is to convert a number, as in (3.45 asMoney: 'US dollar').
We could also "use money to make money", as in (someMoney
withValue: 3.45s).
Make a Money class with these properties. Use the
Testing framework to write a test
suite for it. You should just need to make a single MoneyTestCase class.
Change the payroll system to use Money instead of Numbers to represent
salaries, pay, taxes, etc.