Console.setOut not consistent with System.setOut

75 views
Skip to first unread message

huynhjl

unread,
Jun 29, 2011, 11:34:05 PM6/29/11
to scala-user
Hi All,

I've noticed that Console.setOut behaves differently than
System.setOut.

Console.setOut only affects the current thread while System.setOut
affects the whole JVM. The scaladoc does not indicate that setOut is
restricted to the current thread and I presume most callers would be
surprised by that behavior. Additionally the REPL spawns a thread when
interpreting each line, so Console.setOut does not persist.

I did a bit of investigation and I'm guessing that the change was made
so that Console.withOut would behave properly in a multi-threaded
context. See https://lampsvn.epfl.ch/trac/scala/changeset/6858.

Could setOut be reimplemented so that it affects the whole JVM while
retaining the withOut semantic to override it during a thunk
execution? (along the line of making outVar a var and having setOut
reassigning it to a new DynamicVariable). Or do you think the current
approach is better?

--Jean-Laurent

Jason Zaugg

unread,
Jun 30, 2011, 1:39:42 AM6/30/11
to huynhjl, scala-user
On Thu, Jun 30, 2011 at 5:34 AM, huynhjl <huy...@gmail.com> wrote:
> Hi All,
>
> I've noticed that Console.setOut behaves differently than
> System.setOut.

Here's a previous related discussion:

https://groups.google.com/forum/#!topic/scala-user/lMeSDbgYH5U

-jason

huynhjl

unread,
Jun 30, 2011, 3:39:38 AM6/30/11
to scala-user
Yes, I saw it. Expanding where it left out:

Bill> I discovered just now that Scala's println seems to be caching
the
Bill> System.out reference somehow. Is there a reason for that?
Paul> That's how it was designed. Predef.println is Console.println.
You can
Paul> set Console.out to whatever you want.

# In the REPL: Console.setOut does not do what I expect as it's per
thread (some newlines removed)

scala> val newOut = new java.io.PrintStream(new
java.io.FilterOutputStream(System.out) { override def write(i:Int) { 1
to 2 foreach(_ => out.write(i)) } })
newOut: java.io.PrintStream = java.io.PrintStream@1b3f57d1
scala> Console.setOut(newOut)
scala> println("foo")
foo
scala> System.setOut(newOut)
scala> System.out.println("bar")
bbaarr
scala> println(Thread.currentThread); Console.setOut(newOut)
Thread[Thread-7,5,main]
scala> println(Thread.currentThread); Console.setOut(newOut);
println("foo")
Thread[Thread-8,5,main]
ffoooo

# Exhibit 2: On the other hand, this works fine, as new thread inherit
the Console.out from their parent.

Console.setOut(newOut)
import java.util.concurrent._
val executor = Executors.newFixedThreadPool(2)
def runnable = new Runnable { def run() { println("run") } }
executor.submit(runnable)
executor.submit(runnable)
executor.shutdown

My feeling is that the current Console.setOut is complex to use as one
has to worry about threading.

Interestingly, this gives a sense what people use System.setOut for:
http://google.com/codesearch#search/&q=System.setOut&type=cs
In many case the Console.withOut method would work fine (usually for
testing).

--Jean-Laurent

On Jun 29, 10:39 pm, Jason Zaugg <jza...@gmail.com> wrote:
Reply all
Reply to author
Forward
0 new messages