Smalltalk Birthday Kata Part 3
At the end of Part 2 I had barely working tests for the core logic of the kata.
Referring back to the original Birthday Greetings Kata, it’s clear that Employee
s know about more than just their birth date.
So, let’s get populating those extra fields.
Object subclass: Employee [
<comment: 'I represent an Employee in the Kata.'>
<category: 'BirthdayKata'>
| birthDate firstName lastName email |
Expanding the set of instance variables is the first stage…
Updating the initialization
Employee class >> newBirthdate: aDate firstName: aFirstname lastName: aLastname email: anEmail [
"Answer a new instance of the receiver."
<category: 'basic'>
^self basicNew initBirthdate: aDate firstName: aFirstname lastName: aLastname email: anEmail
]
initBirthdate: aDate firstName: aFirstname lastName: aLastname email: anEmail [
"Initialize the receiver."
<category: 'private-initialization'>
birthDate := aDate.
firstName := aFirstname.
lastName := aLastname.
email := anEmail.
]
This simplifies the construction of the Employee
class a bit.
Refactoring the tests
There was a bit of repetition in the instantiation of the Employee
in the
tests, this can easily be refactored to a factory method.
testIsBirthdayWhenDateIsBirthday [
<category: 'tests'>
| e today birthDate |
birthDate := Date newDay: 14 month: #Feb year: 1990.
today := Date newDay: 14 month: #Feb year: 2019.
e := self newEmployee: birthDate.
self assert: (e isBirthday: today)
]
newEmployee: aBirthdate [
^Employee newBirthdate: aBirthdate firstName: 'John' lastName: 'Smith' email: 'john@example.com'.
]
Updating the console representation
With the new fields, I need to update the printOn:
method:
printOn: stream [
<category: 'printing'>
super printOn: stream.
stream nextPutAll: ' ';
nextPutAll: firstName;
nextPutAll: ' ';
nextPutAll: lastName;
nextPutAll: ' born on ';
print: birthDate;
nextPutAll: ' with email ';
nextPutAll: email
]
There’s some subtlety going on here, nextPutAll:
iterates over the things that
it’s putting on to the stream, for strings, that’s fine, they are series of
characters, but for birthDate
it’s not so simple, it’s not a string, by
calling print:
on the stream, with the birthDate
, it delegates to printOn:
from the Date
class, and provides the stream, this makes the birthDate
display itself in a nice human-readable mannner.
$ gst
GNU Smalltalk ready
st> FileStream fileIn: 'Employee.st'.
FileStream
st> birthDate:= Date newDay: 26 month: #Jul year: 1956.
26-Jul-1956.
st> Employee newBirthdate: birthDate firstName: 'John' lastName: 'Smith' email: 'john@example.com'.
an Employee John Smith born on 26-Jul-1956 with email john@example.com
Why not use print: on all lines?
The message print:
is used to provide a printable represententation, which for strings means that they come out with '
wrapped around them, which we don’t want for the other parts.
Compare:
an Employee' ''John'' ''Smith'' born on '26-Jul-1956' with email ''john@example.com'
Next: reading and parsing Employee
s from the sample CSV data file.