- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
iterating over the iterator bugs
Wed, 2010-01-20, 01:32
It's a little discouraging to have to fix the same bugs more than once,
so I feel like I should wave a flag a little here so everyone is aware
of the issue. I'm not trying to be critical, but there is something
about reintroducing bugs which pushes my buttons. "Your tests should
prevent that" you might say, which I'm sure is true, but even when I
write them they don't catch much. Maybe I need to enroll in a test
writing class.
Last summer I found a bunch of methods which gave wrong results:
https://lampsvn.epfl.ch/trac/scala/changeset/18328
https://lampsvn.epfl.ch/trac/scala/changeset/18330
https://lampsvn.epfl.ch/trac/scala/changeset/18331
https://lampsvn.epfl.ch/trac/scala/changeset/18332
https://lampsvn.epfl.ch/trac/scala/changeset/18333
I checked in 3600 tests:
https://lampsvn.epfl.ch/trac/scala/changeset/18334
It strikes again:
http://lampsvn.epfl.ch/trac/scala/ticket/2927
If you use iterators to do anything, you have to be acutely conscious of
the fact that calling next advances the iterator. In general all these
bugs have the same form.
while (it.hasNext && cond) { ... something involving it.next ... }
if (it.hasNext) someResult
else someOtherResult
it.hasNext is false if you examine the last element, regardless of
whatever check you did on it.
The simplest way to avoid this bug without gyrations is the unfairly
maligned early return.
- while (it.hasNext && !p(it.next()))
- i += 1
- if (it.hasNext) i else -1
+ while (it.hasNext) {
+ if (p(it.next())) return i
+ else i += 1
+ }
+
+ -1