As in any programming language, include useful comments and use descriptive
variable names. Since Smalltalk doesn't include type declarations, some
programmers like to use names such as anArray
or
aStream
for variables to give a hint as to what kind of object
is expected. This has no significance for the Smalltalk compiler, though.
Use indentation consistently in your methods. Make methods short --
typically two browser panes worth of text at most. (Generally the style in
Smalltalk is to make methods shorter than the typical C or C++ procedure.)
If you do end up with a method that keeps getting longer and longer, define
some private auxiliary methods, and then just invoke then using (for
example) self helperMethod
.
Instance variable, argument, and temporary names should start with a
lower-case letter; global and class variables with an upper-case letter.
Unfortunately, underscore isn't a legal part of identifiers in Smalltalk,
so use capitalization to separate words,
e.g. aVeryLongInstanceVarName
.
It is almost always a mistake to write code that tests for the class of an object. For example, in your pinball game, don't write something like
x class = Flipper ifTrue: [...]. x class = BlackHole ifTrue: [...].Instead, turn this around and send a message to
x
so that
flippers and black holes can respond differently:
x hitBy: selfIf you really need to know whether an object obeys some message protocol, define a method to ask. For example, all objects in Smalltalk understand
isNumber
. Numbers return true, everything else returns
false.
Unfortunately the syntax for conditionals in Smalltalk makes nested
conditionals hard to read. You can judiciously use ^ (return) to improve
readibility. Consider the sign
method for Numbers, which
returns -1, 0, or 1 depending on whether the number is negative, zero, or
positive.
Here is a version using nested conditionals:
sign ^ self < 0 ifTrue: [-1] ifFalse: [self > 0 ifTrue: [1] ifFalse: [0]]Compare with:
sign self < 0 ifTrue: [^ -1]. self > 0 ifTrue: [^ 1]. ^ 0The
sign
method isn't too bad, but it gets worse with more
complicated logic. Sometimes it's worth writing an auxiliary method just
so you can return from the middle of the auxiliary method to make the code
clearer. (Remember ^ pops out of nested loops, conditionals, etc.)
Generally, avoid referencing global variables, except for class names.
(Smalltalk Express doesn't always follow this rule ... for example
ClrBlue
is a global variable. In e.g. OTI Smalltalk, you
achieve this effect by writing Color blue
. Often it's more
appropriate to use self
or a message to a class in place of a
global variable. Here's a questionable example from the
Smalltalk haikus the 505
students wrote the other year:
i ride a turtle into object nirvana evan become: nilA haiku in better Smalltalk style would have been:
i ride a turtle into object nirvana self become: nil