2013-05-03 5 views
8

実験的なScala 2.10のリフレクションを使用して、レイジーvalのフィールドでFieldMirror.get()を呼び出そうとするとnullが返されます。リフレクションを使ってレイジーヴァルを評価する方法はありますか? get()関数は、nullを返してはなりません。リフレクションを使用してレイジーヴァルを評価するにはどうすればよいですか?

は、この例を考えてみましょう:私は解決策を発見し

case class Person(val firstName: String, 
        val lastName: String) { 
    lazy val name = firstName + " " + lastName 
} 

import scala.reflect.runtime.{universe => ru} 

val runtimeMirror = ru.runtimeMirror(getClass.getClassLoader) 

val fred = Person("Fred", "Smith") 

val instanceMirror = runtimeMirror.reflect(fred) 

val nameTerm = ru.typeOf[Person].declaration(ru.newTermName("name")).asTerm 

val nameLazy = instanceMirror.reflectField(nameTerm) 

nameLazy.get 
    >>> res8: Any = null 

fred.name 
    >>> res9: String = Fred Smith 

nameLazy.get 
    >>> res10: Any = Fred Smith 
+0

強制的にその怠惰な表現の評価。私はスカラーの細部を知らない。 –

+0

この時点で、私は怠惰なval(FieldMirror)への参照しか持っていないので、単純に評価することはできません。 get()関数は式を返し、簡単に評価することができます。 – vertexshader

答えて

6

。生成される隠されたメソッドがあります:

case class Person(val firstName: String, 
       val lastName: String) { 
lazy val name = firstName + " " + lastName 
} 

import scala.reflect.runtime.{universe => ru} 

val runtimeMirror = ru.runtimeMirror(getClass.getClassLoader) 

val fred = Person("Fred", "Smith") 

val instanceMirror = runtimeMirror.reflect(fred) 

val nameMethod = ru.typeOf[Person].member(ru.newTermName("name")).asMethod 
val nameValue = ru.typeOf[Person].member(ru.newTermName("name")).asTerm 

val nameLazy = instanceMirror.reflectField(nameValue) 
val nameLazyMethod = instanceMirror.reflectMethod(nameMethod) 

nameLazy.get 
    >>> null 

nameLazyMethod() 
    >>> res9: String = Fred Smith 

nameLazy.get 
    >>> res10: String = Fred Smith 
+0

あなたは 'ru.typeOf [Person] .member(ru.newTermName(" name "))を試すこともできます。asTerm.getter' – ghik

関連する問題