55

I'm tearing my hair out trying to figure out how to do the following:

def foo(msf: String, o: Any, os: Any*) = {
    println( String.format(msf, o :: List(os:_*)) )
}

There's a reason why I have to declare the method with an o and an os Seq separately. Basically, I end up with the format method called with a single object parameter (of type List ). Attempting:

def foo(msf: String, o: Any, os: Any*) = {
    println( String.format(msf, (o :: List(os:_*))).toArray )
}

Gives me the type error:

found: Array[Any]

required Seq[java.lang.Object]

I've tried casting, which compiles but fails for pretty much the same reason as the first example. When I try

println(String.format(msg, (o :: List(os:_*)) :_* ))

this fails to compile with implicit conversion ambiguity (any2ArrowAssoc and any2stringadd)

Community
  • 1
  • 1
oxbow_lakes
  • 133,303
  • 56
  • 317
  • 449

2 Answers2

67
def foo(msf: String, o: AnyRef, os: AnyRef*) = 
  println( String.format(msf, (o :: os.toList).toArray : _* ))
James Iry
  • 19,367
  • 3
  • 64
  • 56
  • It compiles but falls over at runtime: Exception in thread "main" java.lang.ClassCastException: scala.$colon$colon cannot be cast to scala.runtime.BoxedObjectArray at scala.runtime.RichString.format(RichString.scala:242) – oxbow_lakes Jun 18 '09 at 06:30
  • Also, where does toList come from? – oxbow_lakes Jun 18 '09 at 07:43
  • Fixed, it works now. I'm filing a bug report - Scala shouldn't have ClassCastExceptions except when you have used asInstanceOf. toList is a method on Iterable[A] – James Iry Jun 18 '09 at 13:09
  • Apparently it's been fixed in the 2.8 branch http://lampsvn.epfl.ch/trac/scala/ticket/1360 – James Iry Jun 18 '09 at 15:13
  • 9
    Why was toArray necessary, though? List is a valid input to : _*. – Daniel C. Sobral Jun 18 '09 at 19:25
  • See http://stackoverflow.com/questions/6051302/what-does-colon-underscore-star-do-in-scala for explanation – Vadzim Dec 08 '13 at 21:49
13
def foo(msf: String, o: AnyRef, os: AnyRef*) =
  println( String.format(msf, o :: os.toList : _* ) )

or

def foo(msf: String, o: AnyRef, os: AnyRef*) =
      println( msf format (o :: os.toList : _* ) )

I much prefer the latter, though it has no locale* support.

  • Scala 2.8 does have locale support with RichString's format.
oxbow_lakes
  • 133,303
  • 56
  • 317
  • 449
Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681