How to add tracing within a 'for' comprehension?

logging, scala

Solution

You could always define your own `trace` function:

def trace[T](x: T) = {
  println(x) // or your favourite logging framework :)
  x
}

Then the for comprehension would look like:

for { 
  outer <- ll
  inner <- trace(outer)
} yield inner

Alternatively, if you want more information printed, you can define `trace` as follows:

def trace[T](message: String, x: T) = {
  println(message)
  x
}

and the for comprehension would look like:

for { 
  outer <- ll
  inner <- trace("Value: " + outer, outer)
} yield inner

EDIT: In response to your comment, yes, you can write `trace` so that it acts to the right of the target! You just have to use a bit of implicit trickery. And actually, it does look much nicer than when applied to the left :).

To do this, you have to first define a class which is `Traceable` and then define an implicit conversion to that class:

class Traceable[A](x: A) { 
  def traced = {
    println(x)
    x
  }
}

implicit def any2Traceable[A](x: A) = new Traceable(x)

Then the only thing you have to modify in the code you have provided is to add `traced` to the end of the value you want to be traced. For example:

for { 
  outer <- ll
  inner <- outer traced
} yield inner

(this is translated by the Scala compiler into `outer.traced`)

Problem

For log tracing inside a `for` comprehension, I've used dummy assignment like this: ``` val ll = List(List(1,2),List(1)) for { outer <- ll a = Console.println(outer) // Dummy assignment makes it compile inner <- outer } yield inner ``` The `a =` bit seems awkward. Is there a cleaner way?

Original source