I want to execute splice() for each argument of my varargs:
import scala.reflect.macros.blackbox
object LoggerMacro {
def log(context: blackbox.Context)
(message: context.Expr[String], arguments: context.Expr[Any]*)
: context.universe.Expr[Unit] = context.universe.reify {
println(message.splice) // Works :)
for (argument <- arguments) {
println(argument.splice) // Fails :(
}
}
}
However, I receive the following error message:
LoggerMacro.scala:9:24
the splice cannot be resolved statically, which means there is a cross-stage evaluation involved.
cross-stage evaluations need to be invoked explicitly, so we're showing you this error.
if you're sure this is not an oversight, add scala-compiler.jar to the classpath,
import `scala.tools.reflect.Eval` and call `<your expr>.eval` instead.
println(argument.splice)
Unfortunately, when I add scala-compiler as dependency and import scala.tools.reflect.Eval, there is still no callable eval method on my expr argument.
How can I access my arguments receiving as varargs?
In Scala 2 it's easier to work with
Treesq"..."(and splicing like$,..$,...$) rather thanExprs (and.splice). So tryBut if you prefer
Exprs/.splicethen you can write yourself a helper transformingSeq[Expr[A]]intoExpr[Seq[A]].The tree is slightly different but runtime result is the same.
You couldn't do
argument.splicebecauseargumentis not anExpr, it's a local variable defined here, in a scope quoted withreify. Trying to splice it is "cross-stage evaluation", you were trying to splice not a value from the current stage (Expr[A]) but from the next stage (A).For the same reason
.eval(calculating anExpr[A]intoA) didn't work.Difference between
.spliceand.evalis that the former just inserts a tree (into a tree) while the latter calculates it (if possible).