In C++ I can write:
#ifdef DEBUG
cout << "Debugging!" << endl;
Is there any equivalent in Scala?
In C++ I can write:
#ifdef DEBUG
cout << "Debugging!" << endl;
Is there any equivalent in Scala?
The conventional idiom is @elidable.
The scaladoc covers your conventional use case:
http://www.scala-lang.org/api/current/scala/annotation/elidable.html
The equivalent form of a C preprocesser #ifdef is a Scala macro:
package app.macros.log
import scala.language.experimental.macros
import reflect.macros.Context
object SimpleMacroLogger {
private val on = true
def info(msg: String): Unit = macro info_impl
def info_impl(c: Context)(msg: c.Expr[String]): c.Expr[Unit] = {
import c.universe._
if (on) {
reify {
println(msg.splice)
}
} else {
reify {
// Nothing
}
}
}
}
to be used with
import app.macros.log.{SimpleMacroLogger => log}
object SimpleMacroLoggerDemo extends App {
log.info("Hello")
}
It's far more complex to code, but it's usage is superior: There is no need for surrounding #ifdef/#endif etc. So it does not clutter up your code.
If you set on to false, the macro removes the logging completely.
Anything within the reify will go into the resulting byte code, the other code is run at compile time. This especially applies to the if (on) ....
If you want the code to only be executed when certain conditions hold, you can use a standard if block:
if (SystemProperties.get("debug.mode").exists(_ == "true") {
println("Debugging!")
}
If you're concerned for whatever reason that the statement shouldn't even appear in the compiled output, then you can use an if-block with a compile-time constant expression. In these cases, javac/scalac will correctly infer that the condition will never be true, and so doesn't even include the bytecode for the block. (Obviously you'll need to modify your build to pull in a constant "true" for debug builds, and "false" for prod builds.)
object Constants {
final val DEBUG = false
}
// ...
if (Constants.DEBUG) {
println("Debugging!")
}