generics - Inconsistency with scala reflection library -
i'm having trouble understanding why using scala's runtime reflection in 2.11.1 gives me seemingly inconsistent results.
i trying inspect type of field contained in java object, one:
import java.util.list; import java.util.arraylist; public class example { private list<integer> listofints; public example () { listofints = new arraylist<integer>(); } }
now suppose have scala program tries reason type of field inside "example:"
import java.lang.class import java.lang.reflect.field import java.util.list import scala.reflect.runtime.{ universe => ru } object inspect extends scala.app { val example = new example val cls = example.getclass val listfield = cls.getdeclaredfield("listofints") println(islisttype(listfield)) // prints false println(islisttype(listfield)) // prints true, subsequent calls def islisttype (field: field): boolean = { /* function returns whether type of field list. based on examples @ http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html */ val fieldcls = field.gettype val mirror: ru.mirror = ru.runtimemirror(getclass.getclassloader) val fieldsym: ru.classsymbol = mirror.classsymbol(fieldcls) val fieldtype: ru.type = fieldsym.totype (fieldtype <:< ru.typeof[list[_]]) } }
in particular code snippet, first call islisttype returns false, , second returns true. if switch type operator <:<
=:=
, first call returns true, , second false.
i have similar function in larger code body, , have found when function part of static object, behavior occurs. not happen when using unparameterized classes. while intended function pure, not case. further experimentation has shown there persistent state held somewhere. if replace islisttype
function straightline code, this:
... val example = new example val cls = example.getclass val listfield = cls.getdeclaredfield("listofints") val fieldcls = listfield.gettype val mirror: ru.mirror = ru.runtimemirror(getclass.getclassloader) val fieldsym: ru.classsymbol = mirror.classsymbol(fieldcls) val fieldtype: ru.type = fieldsym.totype println(fieldtype <:< ru.typeof[list[_]]) // prints false println(fieldtype <:< ru.typeof[list[_]]) // prints false
but if reassign field type after <:<
operator, this:
// replace under fieldsym assignment var fieldtype: ru.type = fieldsym.totype println(fieldtype <:< ru.typeof[list[_]]) // prints false fieldtype = fieldsym.totype println(fieldtype <:< ru.typeof[list[_]]) // prints true
while reassigning field type before <:<
operator gives this:
// replace under fieldsym assignment var fieldtype: ru.type = fieldsym.totype fieldtype = fieldsym.totype println(fieldtype <:< ru.typeof[list[_]]) // prints false println(fieldtype <:< ru.typeof[list[_]]) // prints false
does understand i'm doing wrong here, or @ least have way around this?
the reflection library based on compiler, crying shame. people should demand better. anyway, how is.
here's sample ticket 2 years ago. https://issues.scala-lang.org/browse/si-6826
there persistent state held somewhere
there's nothing but.
addendum: dizzying experience, page through selection of 355 open reflection tickets.
Comments
Post a Comment