Incerteza
Incerteza

Reputation: 34884

The expression prints itself in unexpected order

When I print a log information like this:

val idList = getIdList
log info s"\n\n-------idList: ${idList foreach println}"

It shows me:

1
2
3
4
5
-------idList: () 

That makes sense because foreach returns Unit. But why does it print the list of id first? idList is already evaluated in the previous line (if that's the cause)!

And how to make it print it in expected order - after idList:?

Upvotes: 0

Views: 89

Answers (4)

mikołak
mikołak

Reputation: 9705

This is because you're not evaluating the log string to read what you want, you evaluate it to:

\n\n    -------idList: ()

However, the members of the list appear in the output stream as a side effect, due to the println call in the string interpolation.


EDIT: since clarification was requested by the OP, what happens is that the output comes from two sources:

  1. ${idList foreach println} evaluates to (), since println itself doesn't return anything.
  2. However, you can see the elements printed out, because when the string interpolation is evaluated, println is being called. And println prints all the elements into the output stream.

In other words:

//line with log.info() reached, starts evaluating string before method call
1 //println from foreach
2 //println from foreach
3 //println from foreach
4 //println from foreach
5 //println from foreach
//string argument log.info() evaluated from interpolation
-------idList: () //log info prints the resultant string

To solve your problem, modify the expression in the interpolated string to actually return the correct string, e.g.:

log info s"\n\n-------idList: ${idList.mkString("\n")}"

Upvotes: 5

om-nom-nom
om-nom-nom

Reputation: 62835

Interpolation works in a following way:

  1. evaluate all arguments
  2. substitute their results into resulting string

Upvotes: 1

tuxdna
tuxdna

Reputation: 8487

As pointed out by @TheTerribleSwiftTomato , you need to give an expression that returns a value and has no other side-effect. So simply do it like this:

val idList = getIdList
log info s"\n\n-------idList: ${idList mkString " "}"

For example, this works for me:

val idList = List(1, 2, 3, 4, 5)
println(s"\n\n-------idList: ${idList mkString " "}")

Output:

-------idList: 1 2 3 4 5

Upvotes: 0

Tamere
Tamere

Reputation: 101

println is a Unit function that prints to the standard output, you should use mkstring instead that returns a string

log info s"\n\n-------idList: ${idList.mkString("(", ", ", ")")}"

Upvotes: 0

Related Questions