Warmup: understanding the Money classes
TL;DR
In this exercise we explore the various Money classes, and see how examples are used to cover the features of these classes. We will need these classes next to model Prices.
Building on the Money classes
To simplify the Price modeling exercise somewhat, we assume that we already have classes to model money in different currencies.
An amount of money can be created by sending a currency type to a number, for example:
42 euros.
#euros
is just a factory method that constructs an instance of GtTCurrencyMoney
with euros
as the currency, like this:
GtTCurrencyMoney new amount: 42; currency: GtTCurrency euros.
Task: Have a closer look at the method Number>>#euros
. See that its category is “*GToolkit-Tutorial-Prices
”.
NB: The “category” of a method can be found in the first of two buttons at the bottom right of the method Coder window. The other button distinguishes instance methods from class methods.
Categories starting with *
are
extension methods
that are defined in a
different package
from the class. In this case the package GToolkit-Tutorial-Prices
extends the Number
class with the euros
method, without touching its original Kernel
package.
Using examples to test and explore
This particular example is also an
example method
: GtTMoneyExamples>>#fortyTwoEuros
An
example
is any unary method that has the <gtExample>
pragma, and returns an object. Examples also serve as tests, as we can see with the assertions above. Finally, we can inspect and explore examples.
Task: Inspect the fortyTwoEuros
example by clicking on the
Play and Inspect Example
button. (Black triangle + i.)
See that the result has a dedicated Details
view. See how the view is implemented by ALT-clicking on the
Details
label. Don't worry too much about the details of the implementation for now, but note that it is just a few lines of code.
Open a contextual playground at the bottom of the inspector on the fortyTwoEuros
instance (pull up the handle with the two grey bars) and evaluate (inspect) self isZero
. Click on the grey triangle next to isZero
to open the code bubble and see how it is implemented.
Note that this example is an instance of a GtTCurrencyMoney
, but the example is defined in the classs GtTMoneyExamples
. It is common practice to defined examples in a separate class from the class that they exemplify, just like unit tests for a class X
will be defined in a separate class TestX
. In this case there is a hierarchy of Money classes with GtTMoney
at the root, and we put all the examples in GtTMoneyExamples
.
The Money hierarchy
A GtTCurrency
represents a specific sum of money in a given currency. Its superclass is GtTMoney
, which is the abstract root of the Money hierarchy.
NB: The UML diagram below is live. Click on the classes to browse them.
A GtTMoneyBag
represents a bag of money in multiple currencies, for example:
bagWithEurosAndDollars <gtExample> | bag | bag := self fortyTwoEuros + self fortyTwoDollars. self assert: (bag isKindOf: GtTMoneyBag). self assert: bag monies size equals: 2. ^ bag
Task: Inspect the example above and evaluate self - 42 usd
. What is the class of the result? Is it GtTCurrencyMoney
or GtTMoneyBag
? Can you explain the result? In which method is the class of the result determined?
Task: Explore GtTMoneyExamples
. Can you find an example that tests this scenario in which we remove the euros from a money bag with euros and dollars?
Task: Are there examples for GtTZeroMoney
? What is it used for?
Hint:
Browse the GtTZeroMoney
class and explore the
References
tab. Then look for
Senders
to see where these methods are used.