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
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
@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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With