Transforming Scala varargs into Java Object... varargs
Asked Answered
T

2

14

I have a Java class that logs stuff which has a method like this:

void info(Object message, Object... params);

In Scala, I've created a wrapper around such call that looks like this:

def info(msg: => String, params: Any*) {
  log.info(msg, params);
}

When I call:

val host = "127.0.0.1"
val port = "1234"
info("Start on {0}:{1}", host, port)

I get:

"Started on WrappedArray(127.0.0.1, 1234):{1}"

Now, does anyone now how to convert params into an Object[] that can be consumed properly?

I tried to do:

def info(msg: => String, params: Any*)
  log.info(msg, params.toList.toArray);
}

But that doesn't work:

"Started on [Ljava.lang.Object;@14a18d:{1}"

Similar thing happens when you do:

params.asInstanceOf[WrappedArray[Object]].array
Tyrannosaur answered 25/2, 2010 at 13:19 Comment(0)
T
22

Found the answer:

log.info(msg,  params.map(_.asInstanceOf[AnyRef]) : _*)

The following returns a Seq[AnyRef] => params.map(_.asInstanceOf[AnyRef]), and the ': _*' part tells the compiler to pass it as varargs

Result:

"Started on 127.0.0.1:1234"

Besides, this solution deals with both AnyVals and AnyRefs

Tyrannosaur answered 25/2, 2010 at 13:44 Comment(2)
May I ask you how 'info("Start on {0}:{1}", host, port)' is transformed into "Started on 127.0.0.1:1234" ? Is it your code your standard RichString ?Shakhty
This is transformed by some Java code provided to me. The method that formats is called formatString in anonsvn.jboss.org/repos/infinispan/trunk/core/src/main/java/org/…Kordula
W
14

@Galder - there is an easier way which allows you to avoid the cumbersome asInstanceOf[Object] call:

def info(msg: => String, params: Any*) =  log.info( msg.format(params : _*) );

In scala 2.7, the format(args : Any*) function is implicitly included via RichString (and has a sub-optimal implementation is terms of reflection for no good reason that I can see) whereas in 2.8 the method is included via StringLike and is implemented via a direct call to String.format(String, Object ...)

I understand that the reason why Java does not contain such a method is that it has an implication that "every String is a format String", which is not the case. happily, I'm willing to forgo the logical correctness for the more useable class which scala provides!

Weighty answered 25/2, 2010 at 14:58 Comment(5)
This will create a the log string in any case eagerly, right?Apatetic
That does not compile, it gets confused with the other version of log.info that exists. It cant differentiate between: void info(Object message); and void info(Object message, Object... params);Kordula
That is news to me - it's lifted straight from my production code!Weighty
Oh, I see what you mean. It doesn't compile when next to another fragment of your code. Not exactly worth a -1 but anyway. One suggestion would be to rename the method as logfWeighty
plus one given just to counter the stupid -1Centeno

© 2022 - 2024 — McMap. All rights reserved.