Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any way to access the type of a Scala Option declaration at runtime using reflection?

So, I have a Scala class that looks like this:

class TestClass {
  var value: Option[Int] = None
}

and I'm tackling a problem where I have a String value and I want to coerce it into that Option[Int] at runtime using reflection. So, in another piece of code (that knows nothing about TestClass) I have some code like this:

def setField[A <: Object](target: A, fieldName: String, value: String) {
  val field = target.getClass.getDeclaredField(fieldName)
  val coercedValue = ???; // How do I figure out that this needs to be Option[Int] ? 
  field.set(target, coercedValue)   
}

To do this, I need to know that the field is an Option and that the type parameter of the Option is Int.

What are my options for figuring out that the type of 'value' is Option[Int] at runtime (i.e. using reflection)?

I have seen similar problems solved by annotating the field, e.g. @OptionType(Int.class). I'd prefer a solution that didn't require annotations on the reflection target if possible.

like image 462
Graham Lea Avatar asked Apr 18 '10 21:04

Graham Lea


People also ask

How to use reflection in Scala?

Types obtained through reflection can be instantiated by invoking their constructor using an appropriate “invoker” mirror (mirrors are expanded upon below). Let's walk through an example using the REPL: scala> case class Person(name: String) defined class Person scala> val m = ru. runtimeMirror(getClass.

What is Option [] in Scala?

The Option in Scala is referred to a carrier of single or no element for a stated type. When a method returns a value which can even be null then Option is utilized i.e, the method defined returns an instance of an Option, in place of returning a single object or a null.


Video Answer


1 Answers

It's quite streightforward using Java 1.5 reflection API:

 def isIntOption(clasz: Class[_], propertyName: String) = {
   var result = 
     for {
       method <- cls.getMethods
       if method.getName==propertyName+"_$eq"
       param <- method.getGenericParameterTypes.toList.asInstanceOf[List[ParameterizedType]]
     } yield
       param.getActualTypeArguments.toList == List(classOf[Integer]) 
       && param.getRawType == classOf[Option[_]]
   if (result.length != 1)
     throw new Exception();
   else
     result(0)
 }
like image 199
Alexey Avatar answered Oct 22 '22 14:10

Alexey