Closed sanssushi closed 3 months ago
I doubt that passing these arguments by name into the String Interpolation makes much sense there, since the call of scala.StringContext#s
would lead to macro expansion (or even that call might be replaced to something else by scalac accordingly to scaladoc).
I was stumbling upon this when rewriting logger.debug(...)
to debug"..."
and got very different results, for example
def run: IO[Unit] =
doSomething[IO] *> debug"finished at: ${Clock.systemUTC().instant()}"
logs the time before doSomething
runs vs.
def run: IO[Unit] =
doSomething[IO] *> logger.debug(s"finished at: ${Clock.systemUTC().instant()}")
which logs the time after doSomething
is finished.
Another example:
def run: IO[Unit] =
doSomething[IO] *> debug"this may fail: ${1 / 0}".recover(_ => ())
does not only not recover from a failing log message, but prevents doSomething
from running at all vs.
def run: IO[Unit] =
doSomething[IO] *> logger.debug(s"this may fail: ${1 / 0}").recover(_ => ())
which recovers from a failing log message (after running doSomething
).
From a users perspective the deviation of behaviour seems rather odd. Shouldn't the syntax styles be usable interchangeably? I don't know about Scala macros, but the workaround from above worked for me so I thought why not post it here.
Again, one cannot pass by-name arguments to the scala.StringContext#s
since its implementation is a def-macro. I suggest you not pass anything side-effecting / non-referentially transparent to the logger methods, and you won't see any differences here.
I suggest you not pass anything side-effecting / non-referentially transparent to the logger methods, and you won't see any differences here.
Fair enough. Thanks!
In
MessageLogger
the message is passed by-name, inLoggerInterpolator
by-value.Is there a reason behind that?
If not, should we change the
LoggerInterpolator
like this?I can create a pull request if this makes sense.