Skip to content

Instantly share code, notes, and snippets.

@pawelpanasewicz
Last active August 26, 2019 14:41
Show Gist options
  • Save pawelpanasewicz/8625657 to your computer and use it in GitHub Desktop.
Save pawelpanasewicz/8625657 to your computer and use it in GitHub Desktop.
scala reflection - how to change (not only) private field
import scala.reflect.runtime.universe._
import scala.reflect.ClassTag
def setField[O: ClassTag, FV](obj: O, fieldName: String, fieldValue: FV)(implicit ev: TypeTag[O]): O = {
import scala.reflect.api.JavaUniverse
val ru: JavaUniverse = scala.reflect.runtime.universe //runtime universe
val runtimeMirror: ru.type#Mirror = ru.runtimeMirror(obj.getClass.getClassLoader)
val instanceMirror: ru.type#InstanceMirror = runtimeMirror.reflect(obj)
val fieldTerm: ru.type#TermName = ru.newTermName(fieldName)
val fieldSymbol: ru.type#TermSymbol = ru.typeOf[O].declaration(fieldTerm).asTerm.accessed.asTerm
val fieldMirror: ru.type#FieldMirror = instanceMirror.reflectField(fieldSymbol)
fieldMirror.set(fieldValue)
obj
}
//usage
case class X(i:Int, d:Double) {
private val s = "I am private"
def showMeS = s
}
val x =X(123, 0.001)
assert(x.i == 123)
assert(x.d == 0.001)
assert(x.showMeS == "I am private")
setField(x, "i", 103)
assert(x.i == 103)
setField(x, "d", 5.001)
assert(x.d == 5.001)
setField(x, "s", "Not any more...")
assert(x.showMeS == "Not any more...")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment