val input = Console....">

Predef.readLine Behavior

scala> val input = readLine("hello %s%n", "world") hello WrappedArray(world) input: String = "" scala> val input = Console.readLine("hello %s%n", "world") hello world input: String = "" 

What is the reason for the difference here? (I also tried to compile it, so this is not a REPL thing.)

Scala version 2.9.0-1

+4
source share
1 answer

There seems to be a bug in Predef :

 def readLine(text: String, args: Any*) = Console.readLine(text, args) 

When I think it should be:

 def readLine(text: String, args: Any*) = Console.readLine(text, args: _*) 

In the first version, you call Prefef.readLine . Due to the missing type of type _* function is called with args as the only first argument of the repeating argument args of Console.readLine .

In the compilation phase without interruption, this single argument is enclosed in a WrappedArray so that it can be thought of as Seq[Any] . Then, the WrappedArray converted using the toString method, and this is what is used for %s in "hello %s%n" . I think this is happening.

In the second version, args treated from the very beginning as Seq[Any] , and the conversion does not occur.

All this is a little ridiculous because the compiler does not allow you to do this at all:

 scala> def f(s: Int*) = s foreach println f: (s: Int*)Unit scala> def g(s: Int*) = f(s) <console>:8: error: type mismatch; found : Int* required: Int def g(s: Int*) = f(s) 

With Any you will go through the typer phase.

+5
source

All Articles