3

実行時に Scala クラスのすべてのプロパティをプログラムで決定したいと考えています。たとえば、次の Scala クラスの場合、メソッドname1name3name4、およびname5が のプロパティのゲッターであることを確認したいと思いAます。

class A(val name1: String, private val name2: String) {
  val name3 = ""
  var name4 = ""
  def name5 = ""
  def name6() = ""
}

ほとんどの作業は、Java のリフレクション API で実行できます。残念ながら、 と の違いを検出できませんでしname5name6()。そのため、ScalaSigParser を使用して次の試行を開始しましたが、残念ながら ScalaSig のname5とのフラグname6()も同じです。これが私のコードです:

def gettersOf(clazz: Class[_]) = {
  for (ssig <- ScalaSigParser.parse(clazz))
  yield {
    ssig.symbols.toList.collect{
      case m: MethodSymbol => m
    }.filter(m => (m.symbolInfo.flags & 0xFFFFF) == 0x200)
  }
}

gettersOf(classOf[A]).get.foreach{m =>
  println(m.name + ": " + m)
}

次の出力でわかるように、両方のメソッドはinfo値のみが異なります。

name1: MethodSymbol(name1, owner=0, flags=28400200, info=22 ,None)
<init>: MethodSymbol(<init>, owner=0, flags=200, info=38 ,None)
name3: MethodSymbol(name3, owner=0, flags=8400200, info=45 ,None)
name4: MethodSymbol(name4, owner=0, flags=8000200, info=45 ,None)
name4_$eq: MethodSymbol(name4_$eq, owner=0, flags=8000200, info=54 ,None)
name5: MethodSymbol(name5, owner=0, flags=200, info=45 ,None)
name6: MethodSymbol(name6, owner=0, flags=200, info=66 ,None)

ただし、info静的定数を返していないようです。クラスに別のメソッドを追加すると、ある程度の安定性があるように見えますが、のinfoname6が変化します。

  • name3name4、およびname5常に同じinfo値を持つ
  • name6name5常に異なるinfo値を持っている

誰かがその意味とinfo、それを使用してどのような方法であるかを確実に判断する方法を知っていますか?

関連する質問:

4

3 に答える 3

8

最善の策は、来たるScala2.10のリフレクションAPIを使用することです。

2.10.0-M6で型のプロパティを取得する方法は次のとおりです。

scala> import reflect.runtime.universe._
import reflect.runtime.universe._

scala> typeOf[A].members.view.filter{_.isValue}.filter{!_.isMethod}.toList
res0: List[reflect.runtime.universe.Symbol] = List(variable name4, value name3, value name2, value name1)

残念ながら、まだ多くの読み物はありません。ただし、SOについてはいくつかの回答済みの質問があります。たとえば、この質問はあなたにとって興味深いかもしれません。DanielSobralによるこのブログ投稿もチェックしてください。

于 2012-08-13T13:44:18.333 に答える
3
import reflect.runtime.universe._
typeOf[A].members map (m => m -> m.typeSignature) collect { 
  case (m, nm: NullaryMethodType) => m 
}
于 2012-08-13T14:28:06.380 に答える
0

私はついに解決策を見つけました。プリミティブinfo値を使用する代わりに、括弧がないすべてのメソッドに対してinfoTypeを返すように見える、より有益なものを使用できます。NullaryMethodType

def gettersOf(clazz: Class[_]) = {
  for (ssig <- ScalaSigParser.parse(clazz))
  yield {
    ssig.symbols.toList.collect {
      case m: MethodSymbol => m
    }.filter(m => (m.symbolInfo.flags & 0xFFFFF) == 0x200 && m.infoType.isInstanceOf[NullaryMethodType])
  }
}

name6最終的に、非表示の<init>メソッドを使用した場合と使用しない場合で、目的の結果が得られます。

name1: MethodSymbol(name1, owner=0, flags=28400200, info=22 ,None)
name3: MethodSymbol(name3, owner=0, flags=8400200, info=45 ,None)
name4: MethodSymbol(name4, owner=0, flags=8000200, info=45 ,None)
name5: MethodSymbol(name5, owner=0, flags=200, info=45 ,None)
于 2012-08-13T13:16:57.527 に答える