目的
Scala 2.10から、メタプログラミングの一種であるリフレクション機能が入っています。
Reflection - 概要 - Scala Documentation
import scala.reflect.runtime.universe._
宇宙をインポートとか熱いですね……!
遊んでみたかったので、型を与えると簡易ScalaDocを出力するようなもの、つまり、
printMethods[List[Int]]
とすると、Scala Standard Library 2.11.2 - List のメソッド抜粋のような感じで、
...
addString(b: StringBuilder): StringBuilder
addString(b: StringBuilder, sep: String): StringBuilder
addString(b: StringBuilder, start: String, sep: String, end: String): StringBuilder
aggregate[B](z: => B)(seqop: (B, A) => B, combop: (B, B) => B): B
andThen[C](k: B => C): PartialFunction[A,C]
apply(n: Int): A
applyOrElse[A1][B1](x: A1, default: A1 => B1): B1
asInstanceOf[T0]: T0
...
を出力するものを、Scala2.11で書いてみました。
ただし、型パラメータのlower/upper boundの取得方法が分からずじまい……。
コード
リフレクションはまだEXPERIMENTALな機能なので、Scala 2.12以上では動かなくなるかも。
2.10で書いたコードを2.11に上げたら、deprecatedになっているものが幾つかありました。
HelloUniverse.scala
object HelloUniverse extends App {
implicit class RichList[T](self: List[T]) {
def mkStringIfNonEmpty[T](start: String,
seq: String,
end: String): String =
if (self.nonEmpty) self.mkString(start, seq, end)
else ""
}
import scala.reflect.runtime.universe._
def paramToString(param: Symbol): String =
(if (param.isImplicit) "implicit " else "") +
param.name +
": " +
param.typeSignature
def methodToString(method: MethodSymbol): String =
method.name.decodedName +
method.typeParams.map(
_.name
).mkStringIfNonEmpty("[", "][", "]") +
method.paramLists.map(
_.map(paramToString).mkString(", ")
).mkStringIfNonEmpty("(", ")(", ")") +
": " +
method.returnType
def printMethods[T: TypeTag] =
typeOf[T].
members.
filter(_.isMethod).
map(_.asMethod).
map(methodToString).
toArray.
sorted.
foreach(println)
printMethods[List[Int]]
}
build.properties
sbt.version=0.13.6
build.sbt
name := "hello_universe"
version := "1.0"
scalaVersion := "2.11.2"
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value