I am trying to solve a problem given by the Book “Scala for the Impatient”, which asked to implement java’s BufferedInputStream as a trait. Here is my implementation,
trait Buffering {
this:InputStream =>
private[this] val bis = {
new JavaBufferedInputStream(this)
}
override def read = bis.read
override def read(byte:Array[Byte], off:Int, len:Int) = bis.read(byte, off, len)
override def available = bis.available
override def close() {
bis.close
}
override def skip(n:Long) = bis.skip(n)
}
def main(args:Array[String]) {
val bfis = new FileInputStream(new File("foo.txt")) with Buffering
println(bfis.read)
bfis.close
}
But this give me a java stackoverflow error, so what’s wrong with it? Thanks!
It looks like you are getting a stack overflow where you don’t expect one. The key to troubleshoot these is to look at the repeating cycle of the stack trace. It usually points to what is repeatedly allocating frames. Here it will show something like that:
So reading from bottom to top, it looks like your
read(byte, ...)is callingbis.read(byte, ...)which is callingBufferedInputStream.readwhich is then calling yourread(byte, ...)again.It would appear that
new BufferedInputStream(this)is callingreadon the underlyingInputStreambut since the underlyingthisis your object that then delegates calls onbiswe have infinite recursion.I’m guessing that the author wants you to use the
abstract overridestackable modifications pattern where you can usesuperto refer to the rightreadmethod.