3
object Rec extends App {
  val outStream = new java.io.ByteArrayOutputStream
  {
    val out = new java.io.PrintStream(new java.io.BufferedOutputStream(outStream))
  }
}

This seemingly simple code causes a compile error:

$ scalac rec.scala
rec.scala:2: error: recursive value out needs type
  val outStream = new java.io.ByteArrayOutputStream
                  ^
one error found

But I don't see what is "recursive."

Scala compiler version 2.11.7 -- Copyright 2002-2013, LAMP/EPFL

Background: I was trying to write a unit test on println with Console.withOut

nodakai
  • 7,773
  • 3
  • 30
  • 60

2 Answers2

4

You are assigning a value to outStream by invoking stuff to which you pass on the outStream (I marked it in CAPS). Hence the recursion.

object Rec extends App {
  val OUTSTREAM = new java.io.ByteArrayOutputStream
  {
    val out = new java.io.PrintStream(new java.io.BufferedOutputStream(OUTSTREAM))
  }
}
slouc
  • 9,508
  • 3
  • 16
  • 41
4

After putting braces where they belong code looks like this:

object Rec extends App {
  val outStream = new java.io.ByteArrayOutputStream {
    val out = new java.io.PrintStream(new java.io.BufferedOutputStream(outStream))
  }
}

and this is how you create object of an anonymous class with a member out that uses the defined object recursively (outStream uses outStream in its definition).

I believe this is what you wanted to do

object Rec extends App {
  val outStream = new java.io.ByteArrayOutputStream
  val out = new java.io.PrintStream(new java.io.BufferedOutputStream(outStream))
}

If you for some reason need to create another scope, you can use locally

What does Predef.locally do, and how is it different from Predef.identity

Community
  • 1
  • 1
Łukasz
  • 8,555
  • 2
  • 28
  • 51