0

As a data scientist I frequently use the following pattern for data extraction (i.e. DB, file reading and others):

val source = open(sourceName)
var item = source.getNextItem()
while(item != null){
    processItem(item)
    item = source.getNextItem()
}
source.close

My (current) dream is to wrap this verbosity into a Scala object "SourceTrav" that would allow this elegance:

SourceTrav(sourceName).foreach(item => processItem(item))

with the same functionality as above, but without running into StackOverflowError, as might happen with the examples in Semantics of Scala Traversable, Iterable, Sequence, Stream and View?

Any idea?

Community
  • 1
  • 1
EliG
  • 1
  • 2

1 Answers1

0

If Scala's standard library (for example scala.io.Source) doesn't suit your needs, you can use different Iterator or Stream companion object methods to wrap manual iterator traversal.

In this case, for example, you can do the following, when you already have an open source:

Iterator.continually(source.getNextItem()).takeWhile(_ != null).foreach(processItem)

If you also want to add automatic opening and closing of the source, don't forget to add try-finally or some other flavor of loan pattern:

case class SourceTrav(sourceName: String) {
  def foreach(processItem: Item => Unit): Unit = {
    val source = open(sourceName)
    try {
      Iterator.continually(source.getNextItem()).takeWhile(_ != null).foreach(processItem)
    } finally {
      source.close()
    }
  }
}
Kolmar
  • 14,086
  • 1
  • 22
  • 25