最近、ちょっとしたところでScalaのリフレクションを使おうとして、思っていた以上に忘れていてなかなかハマってしまったのがちょっと悔しくて、これを機にまとめてみようかなと思いました。
3回くらいに分けて書くつもりです。よろしければ、お付き合いください。
*結局、5回になりました
書いたエントリのまとめは、こちらです。
導入編
http://d.hatena.ne.jp/Kazuhira/20130730/1375192075
定義情報取得編 - 1
http://d.hatena.ne.jp/Kazuhira/20130801/1375370390
定義情報取得編 - 2
http://d.hatena.ne.jp/Kazuhira/20130803/1375526971
インスタンス操作編
http://d.hatena.ne.jp/Kazuhira/20130804/1375604912
オマケ
http://d.hatena.ne.jp/Kazuhira/20130804/1375607954
今回は、頭出し。
Scalaのリフレクションって?どのバージョンから使えるの?
Scala 2.10.0から実験的に導入された、Scala独自のリフレクションです。Scala 2.9以前のリフレクションといえば、ClassManifestを使って型情報を取得したり、Javaのリフレクションを使う必要がありました。
これらのAPIでは、Scala独自の情報、varで宣言されてるの?とか、トレイトなの?、implicitが付与されているの?みたいなものが取得できるようになります。
使うのに、何か環境揃える必要あるの?
Scalaのリフレクションを使用するには、「scala-reflect.jar」というJARファイルが必要です。
Scalaのオフィシャルサイトで配布されているディストリビューションには、libディレクトリに含まれているのでScalaの各種コマンド(scala/scalac/fsc)で使う分には何も用意する必要がありません。
ただ、sbtを使っている場合は、依存関係の追加が必要です。以下は、Scala 2.10.2のscala-reflect.jarを依存関係に追加している例です。
libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.10.2"
あとは、Reflection APIに対して、import文を書くことになります。
import scala.reflect.runtime.{universe => ru}
さらに、上記ruのメンバを丸っとimportしているのも、よく見かけます。
import ru._
個人的には、なんとなく
import scala.reflect.runtime.universe
で止めておきたいところですが。
参考ドキュメントとかあります?
まずは、オフィシャルサイトの機能紹介を。
REFLECTION
http://docs.scala-lang.org/overviews/reflection/overview.html
日本語訳
http://docs.scala-lang.org/ja/overviews/reflection/overview.html
その他にも、少々。
Scala 2.10 におけるメタプログラミング: 構文木、シンボル、型について
http://eed3si9n.com/ja/metaprogramming-in-scala-210
Scala 2.10 Reflection and Macros
http://hexx.github.io/pshow-scala-reflection/out/#0
このブログでも、2回取り扱いました。
http://d.hatena.ne.jp/Kazuhira/20130121/1358775647
http://d.hatena.ne.jp/Kazuhira/20130121/1358780334
が、そこで終わってたので、もうちょっと頑張ってみようと思い立ったのが、今回書いたきっかけです。
主に見るべきクラスは?
そこそこ数もある上、scaladoc上でどうにも追いにくい気がするのですが、とりあえずこんなところでしょうか。
Universe
http://www.scala-lang.org/api/current/index.html#scala.reflect.api.Universe
JavaUniverse(上述のimportしたuniverseの実体です)
http://www.scala-lang.org/api/current/index.html#scala.reflect.runtime.JavaUniverse
TypeTag
http://www.scala-lang.org/api/current/index.html#scala.reflect.api.TypeTags$TypeTag
Type
http://www.scala-lang.org/api/current/index.html#scala.reflect.api.Types$Type
Types
http://www.scala-lang.org/api/current/index.html#scala.reflect.api.Types
Symbol
http://www.scala-lang.org/api/current/index.html#scala.reflect.api.Symbols$Symbol
Symbols
http://www.scala-lang.org/api/current/index.html#scala.reflect.api.Symbols
StandardNames
http://www.scala-lang.org/api/current/index.html#scala.reflect.api.StandardNames
MemberScope
http://www.scala-lang.org/api/current/index.html#scala.reflect.api.Scopes$MemberScope
Mirror
http://www.scala-lang.org/api/current/index.html#scala.reflect.api.Mirror
次回以降は、サンプルを載せつつ書いていきたいと思います。