Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Scala variable name at runtime

Tags:

scala

Is it possible to get the name of a scala variable at runtime?

E.g. is it possible to write a function getIntVarName(variable: Int): String behaving as follows?

val myInt = 3
assert("myInt" === getIntVarName(myInt))
like image 661
user523071 Avatar asked Feb 19 '11 12:02

user523071


2 Answers

For what you need to do, It seems to me that runtime is not required, since you already have your myInt variable defined at compile time. If this is the case, you just need a bit of AST manipulation via a macro.

Try

package com.natalinobusa.macros

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context

object Macros {

  // write macros here
  def getName(x: Any): String = macro impl

  def impl(c: Context)(x: c.Tree): c.Tree = {
    import c.universe._
    val p = x match {
      case Select(_, TermName(s)) => s
      case _ => ""
    }
    q"$p"
  }
}

Be aware that macro's must be compiled as a separate subproject, and cannot be part of the same project where the macro substitution has to be applied. Check this template on how to define such a macro sub-project: https://github.com/echojc/scala-macro-template

scala> import Macros._
import Macros._

scala> val myInt = 3
myInt: Int = 3

scala> "myInt" == getName(myInt)
res6: Boolean = true
like image 151
natbusa Avatar answered Nov 11 '22 17:11

natbusa


You can use scala-nameof to get a variable name, function name, class member name, or type name. It happens at compile-time so there's no reflection involved and no runtime dependency needed.

val myInt = 3
assert("myInt" === nameOf(myInt))

will compile to:

val myInt = 3
assert("myInt" === "myInt")
like image 22
dwickern Avatar answered Nov 11 '22 17:11

dwickern