算譜王におれはなる!!!!

偏りはあると思うけど情報技術全般についてマイペースに書くよ。

Kotlin 便利なプラグインが2つ登場しRealmが捗るよ〜

blog.jetbrains.com

Kotiln 1.0.6がリリースされました! 同時に面白いプラグインが2つリリースされました。 all-open compiler pluginとno-arg compiler pluginです。

all-open compiler pluginは、指定したアノテーションがついたクラスが自動でopen指定されるという機能を持ちます。 no-arg compiler pluginは、指定したアノテーションがついたクラスに、自動でデフォルトコンストラクタ(引数を持たないコンストラクタ)を生成してくれます。

導入方法は、冒頭に示したKotlin公式ブログを参照してください。

今回はこれらのプラグインを用いることで、Realmが使いやすくなることを示したいと思います。

プラグインなし

まずは普通にKotlinだけを使って、Realmオブジェクトを定義してみます。

open User(@PrimaryKey open var id: Long = 0,
          open var name: String = ""): RealmObject

うひゃー、おまじないだらけですね。

openが3回も登場していますが、RealmがこのUserクラスを継承して面白い機能を追加するために必要なのです。

また、Realmはデフォルトコンストラクタを要求します。 そのためUserクラスのプライマリコンストラクタでデフォルト引数を与えることで、引数なしのコンストラクタを提供しているというわけです。

ともかく、本来であれば無視してもよいことに注意しなければならないのですね〜。

all-open compiler pluginを使う

all-open compiler pluginを使って、open修飾子を退治しましょう。 プラグインの設定として、下記をbuild.gradleに記述します。

allOpen {
    annotation('io.realm.annotations.RealmClass')
}

この設定により、@RealmClassアノテーションが付いたクラスが、自動でopen指定となります。

@RealmClass
User(@PrimaryKey var id: Long = 0,
     var name: String = ""): RealmObject

no-arg compiler pluginを使う

次にno-arg compiler pluginを使って、デフォルト引数を毎回記述する退屈な作業から解放されましょう。 プラグインの設定として、下記をbuild.gradleに記述します。

noArg {
    annotation('io.realm.annotations.RealmClass')
}

all-openのときと同じように、@RealmClassが付いたクラスを対象に、デフォルトコンストラクタの自動生成を設定します。

ついにやりました! 謎のopenもデフォルト引数も、キレイに消えたコードが手に入りました!

@RealmClass
class User(@PrimaryKey var id: Long,
           var name: String) : RealmObject()

おまけ

no-argで自動生成したデフォルトコンストラクタは、Kotlinのリフレクション機能を使ってもアクセスすることはできないようです。 一方Javaのリフレクション機能を使うとアクセスできます。

@MyAnnotation // このアノテーションに対してno-arg設定
data class Hoge(val value: String)
Hoge::class.constructors.forEach(::println)
println("----------")
Hoge::class.java.constructors.forEach(::println)
println("----------")
println(Hoge::class.java.newInstance())

実行すると...

fun <init>(kotlin.String): Hoge
----------
public Hoge()
public Hoge(java.lang.String)
----------
Hoge(value=null)