Money

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.