Rewind! (was Re: Back to the issue... (was RE: Squeak coding
style...))
Markus Gaelli
gaelli at emergent.de
Mon Mar 8 15:45:12 UTC 2004
Hi Göran,
> Now, *forget* my ideas. I want to hear creative good ideas from you!
> How
> do we improve the quality of the standard packages? Think broad now,
> don't only think about code conventions or class comments.
>
> I know for example Steph will rightly so push unit tests :) but before
> you do that Steph - don't just say "We should all write tests!" :) Try
> to come up with some idea, mechanism, tool or proposal that actually
> would have a chance of *moving us* in that direction.
One little thing which could have great impact on the quality of the
code, would
be to use the little Object>>assert: mechanism, which is there since
long time,
waiting to be used in all kinds of pre- and postconditions and
invariants.
I did a little counting and while we have more than 1000 unit tests
(great) in the image
right now we have only 23 (!) occurrences of assert: sent somewhere
outside a unit test.
Romain Robbes digged out an assert: mechanism of Vassili Bykov
http://www.smalltalkchronicles.net/edition2-1/st_compiler.htm
which won't do any time penalty if switched off. Romain will introduce
that soon
(sorry Romain, hope I did not spoil too much here ;-)
Enhancing the current implementation
Object >> assert: aBlock
"Throw an assertion error if aBlock does not evaluates to true."
aBlock value ifFalse: [AssertionFailure signal: 'Assertion failed']
with something like
assert: aBlock
"Throw an assertion error if aBlock does not evaluates to true."
(UseAssertions ifFalse: [^self].
aBlock value ifFalse: [AssertionFailure signal: 'Assertion failed']
would not take too much time from our programs also, if one set
UseAssertions to false.
In my experience from industry, to have invariants, pre- and
postconditions can be really
powerful. Enhancing some classes which have strong invariants can
really be an interesting
challenge... :-)
A concrete "Todo" would be to move as many assertions of our 1000 unit
tests into the
code as possible. It's interesting what you can abstract here. The
trick is, to _keep_ the tests,
though they don't have any assertions inside them, as long as their
directly tested methods have
some assertions, they are still tests.
And suddenly one test might not only test one but several assertions.
And our assertions are called
in somehow unexpected circumstances. And they document the code.
An example where one might want to move an already abstract assertion
from the test in the
code could be
Random >> next
"Answer a random Float in the interval [0 to 1)."
^ (seed _ self nextValue) / m
One could replace the comment with some active code from
RandomTest >> testNext
10000 timesRepeat: [
| next |
next := gen next.
self assert: (next >= 0).
self assert: (next < 1)].
and end up with:
Random >> next
|aResult|
aResult:= (seed _ self nextValue) / m.
self assert: [aResult >= 0].
self assert: [aResult < 1].
^aResult
and
RandomTest >> testNext
10000 timesRepeat: [gen next]
Cheers,
Markus
More information about the Squeak-dev
mailing list
|