2012-06-18 6 views
4

Следуя за this question, я пытаюсь выяснить, как вызвать метод для объекта. Соответствующие определения:Ошибка отражения Scala: это внутренний модуль, используйте mirrorModule для экземпляра InstanceMirror, чтобы получить его ModuleMirror

trait ThirdParty { def invoke = println("right") } 
trait WeatherIcon { def invoke = println("wrong") } 
class MyClass { 
    object objA extends ThirdParty 
    object objB extends WeatherIcon 
} 

Я получил Symbol для objA как это:

import reflect.runtime.universe._ 

val stuff = typeOf[MyClass].members.filter(_.isValue).filter(_.typeSignature <:< typeOf[ThirdParty]) 

Это возвращает Iterable с одним элементом, так скажем:

val objASymbol = stuff.head.asModuleSymbol 

Я тогда попытался, исходя из this other question, это:

val mirror = runtimeMirror(getClass.getClassLoader) 
mirror.reflectModule(objASymbol) 

что привело к сообщению об ошибке цитируемого по теме:

java.lang.Error: this is an inner module, use reflectModule on an InstanceMirror to obtain its ModuleMirror 
    at scala.reflect.runtime.JavaMirrors$JavaMirror.reflectModule(JavaMirrors.scala:118) 
    at scala.reflect.runtime.JavaMirrors$JavaMirror.reflectModule(JavaMirrors.scala:60) 

Проблема заключается в том, что я не могу понять, что это сообщение об ошибке говорит мне делать!

+0

В вашем примере, что такое 'res6'? – Nicolas

+0

@Nicolas Извините, я скопировал с неправильного места. Это просто «objASymbol», о котором я говорил ранее. –

ответ

6

Вам необходимо написать runtimeMirror.reflect(<instance of MyClass>).reflectModule(objASymbol). Plain reflectModule не будет работать, потому что некоторые отражающие операции на objA (например, получение его экземпляра) требуют внешнего экземпляра.

К сожалению, ваш прецедент не будет работать, даже если вы его правильно напишете, потому что M4 поддерживает только статические объекты: https://issues.scala-lang.org/browse/SI-5498. Мы выполним это до финала 2.10.0.