他の誰も有効な答えを思いつかない場合、メソッド シグネチャに基づいてコード ジェネレーターを作成するのはそれほど難しいことではないと思います。
val a = classOf[String].getMethods.map(_.toString).filter(s =>
s.contains("public") && s.contains("static")
)
String
たとえば、すべてのメソッド シグネチャ (この場合は for) を文字列として引き出します。それで
val b = a.map(_.split(" ").reverse.take(2).reverse)
戻り値の型が前に分割された関数シグネチャのみを取得します。今
val c = b.map(_(1).dropWhile(_ != '(').drop(1).takeWhile(_ != ')').split(","))
val d = b.map(_(1).takeWhile(_ != '('))
引数のシグネチャと関数の名前をそれぞれ取得します。次に、プリミティブ型を変換する必要があります。これは、最初の文字を大文字にするだけでよいため、非常に簡単です (ユニットになる void を保存します)。
def jprim2scala(s: String) = {
val prim = List("boolean","byte","short","char","int","long","float","double")
def arrayconvert(s: String): String = {
if (s.endsWith("[]")) "Array["+arrayconvert(s.substring(0,s.length-2))+"]"
else if (s=="void") "Unit"
else if (prim contains s) {
s.substring(0,1).toUpperCase + s.substring(1)
}
else s
}
arrayconvert(s)
}
def e = (b,c).zipped.map((bi,ci) => (jprim2scala(bi(0)), ci.map(jprim2scala)))
最後に、すべてを元に戻すことができます。
val f = (d,e).zipped.map((name,ei) => {
val (ret,args) = ei
val lastname = name.split('.').last
"def "+lastname+"(" +
(for ((a,i) <- args.zipWithIndex) yield ("a"+i+": "+a)).mkString(", ") +
"): "+ret+" = "+name+"("+(0 until args.length).map("a"+_).mkString(",")+")"
})
これで、適切なシングルトンに (手動で) 配置できる Scala コードの束ができました。
object Stringleton {
// The contents of this is cut-and-paste f.map(" "+_).foreach(println)
def valueOf(a0: java.lang.Object): java.lang.String = java.lang.String.valueOf(a0)
def valueOf(a0: Array[Char]): java.lang.String = java.lang.String.valueOf(a0)
def valueOf(a0: Array[Char], a1: Int, a2: Int): java.lang.String = java.lang.String.valueOf(a0,a1,a2)
def valueOf(a0: Boolean): java.lang.String = java.lang.String.valueOf(a0)
def valueOf(a0: Char): java.lang.String = java.lang.String.valueOf(a0)
def valueOf(a0: Int): java.lang.String = java.lang.String.valueOf(a0)
def valueOf(a0: Long): java.lang.String = java.lang.String.valueOf(a0)
def valueOf(a0: Float): java.lang.String = java.lang.String.valueOf(a0)
def valueOf(a0: Double): java.lang.String = java.lang.String.valueOf(a0)
def copyValueOf(a0: Array[Char], a1: Int, a2: Int): java.lang.String = java.lang.String.copyValueOf(a0,a1,a2)
def copyValueOf(a0: Array[Char]): java.lang.String = java.lang.String.copyValueOf(a0)
def format(a0: java.lang.String, a1: Array[java.lang.Object]): java.lang.String = java.lang.String.format(a0,a1)
def format(a0: java.util.Locale, a1: java.lang.String, a2: Array[java.lang.Object]): java.lang.String = java.lang.String.format(a0,a1,a2)
}
(ちなみに、Varargs はここでは機能しません。存在する場合は修正する必要があります。.isVarArgs
メソッド自体 (文字列表現ではない) からメソッドに戻り、最後の Array[X ] を X* に変換し、それを として呼び出しますai: _*
。)
このアプローチの良いところは、一般的なメソッドがある場合、それらを引き出すために構造型付けを使用する必要さえないことです。ラップされたメソッドが継承する独自のトレイトを定義できます! (そして、あなたが特に野心的であれば、ほぼ一致するが完全には一致しないメソッドを、実際に一致するように押し込むことができます。たとえば、すべてが同じメソッド名を持つようにすることができます。)