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

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

Kotlin Birthday Party を開催したよ〜 #jkug

f:id:ngsw_taro:20160226235729j:plain

はい、本日、2月26日に開催しました!

kotlin.doorkeeper.jp

めっちゃくちゃ楽しかったです!!!!!

私が発表したスライドです。 Kotlin1.0のリリースまでの歴史を振り返りました。 やはり、Kotlinは発表当初から"pragmatic"を一貫しているのが素晴らしいと思いました。

KotlinでJUnitするためのライブラリつくったよ〜

作りました。

なぜか?

RobolectricでKotlinしたかったんですが、JUnit(というかhamcrest)が使いづらくて。。

と言っても、1つだけ。

assertThat(actual, `is`(expected))

この`is`、すっごくイケてないw

isってKotlinでは予約語なので、`で括ってやる必要があるのです。

で、作りました。

github.com

その名もknit(ニット)。

かわいいし、字面が Kotlin + JUnit な感じを出しているので気に入っています。

このknitによって、先ほどのコードは次のように記述できます。

actual.should be expected

わぁ、かわいい。

他にもいくつかの便利なAPIを用意しています。

よかったら、コードを読んでみてください。あと☆ください。かわいいアイコンもつくって欲しい。

#DroidKaigi でKotlinの発表してきたよ〜2016

f:id:ngsw_taro:20160219140057j:plain

2月18日、19日に開催されたDroidKaigi 2016に行ってきました。 19日には、50分枠でKotlinについて発表しました! スライドは、最後に載せておきます。 動画は後日公開されるようなので、チェックしてみてください。 運営のみなさま、ありがとうございました〜!!

CFP

講演応募は一番乗りでした。 しかも、かなり気合の入った内容で応募しました。 前回のDroidKaigiでKotlinの導入的な話をしたので、 今回はもっと実践的なもの、かつ私ならではの内容になるように意識しました。

発表

15日のKotlin 1.0リリースが影響してか、参加者のKotlinに対する関心の高さが伺えました。

何回やっても緊張はするものですね。 言葉がすっと出て来ないことが何回かあったし、言い間違えもありましたが、 早口にならず、丁寧にしゃべれたんじゃないかなと思います。

反省点は、少し難しい内容になってしまったかな、というところです。 いや、正確には、対象者や前提知識をもっとアナウンスすべきでした。

再演のご依頼とかあればお気軽にどうぞ!!

懇親会

寿司、おいしかったです。 いろんな人とお話しできました。 三日三晩飲んでました(レセプションパーティー含め)。 かんぞうだいじに!

スライド

英語、あるいは技術的な誤りがあったら、ご指摘いただけると嬉しいです。 今回、英語スライドに挑戦してみましたが、日本語スライドと比べると公開したあとの反響が少ないような印象を受けました。 実際はどうなんだろうか。。

"double context extension" pattern (命名適当) #kotlin

任意の型Aの拡張関数の中でエンクロージング型Bのメンバを使いたいとき、 次のようなコードは自然ですが、fooBの中でしか使えなくて不便です。

When we want to use a enclosing type B's members in any type A's extension function, the following code looks natural, but it's inconvenient that foo can be called in only B.

class B {
  fun A.foo() {...}
}

下記のように同じ定義を繰り返さなくてはなりません。 なぜならFragmentActivityをいじることはできないからです。

Same definitions repeat as the below code because we cannot modify the sourcecode of FragmentActivity.

class RedActivity: FragmentActivity() {
  fun DialogFragment.show(tag: String?) {
    show(supportFragmentManager, tag)
  }
}
class BlueActivity: FragmentActivity() {
  fun DialogFragment.show(tag: String?) {
    show(supportFragmentManager, tag)
  } 
}

そんなとき2つの提案があります。 1つめはインタフェースを使います。

Now I have two suggestions. The first is way to use a interface.

interface DialogFeature {
  fun getSupportFragmentManager(): FragmentManager
  fun DialogFragment.show(tag: String?) {
    show(getSupportFragmentManager(), tag)
  }
}
class RedActivity: FragmentActivity(), DialogFeature {
  fun showMessage() {
    myDialog.show("tag")
  }
}

2つめは、拡張関数を返す拡張プロパティを定義することです。

The second is way to define an extension property which return an extension function.

val FragmentActivity.show: DialogFragment.(String?) -> Unit
  get() = { tag ->
    show(supportFragmentManager, tag)
  }

class RedActivity: FragmentActivity() {
  fun showMessage() {
    myDialog.show("tag")
  }
}

myDialog.show("tag")はこう解釈できます。 「this.showプロパティが参照されたので、DialogFragmentの拡張関数を返し、myDialogをレシーバ、"tag"を引数として呼び出す」

myDialog.show("tag") can be interpreted: "this.show property was refered so it'll return DialogFragment's extension function and then call it with myDialog as a receiver and "tag" as an argument."

この方法だとIntelliJ IDEAのKotlinプラグインによる補完が効きません。 myDialog.のあとにサジェストされるメンバに、FragmentActivityの拡張プロパティであるshowは表示されません。

Code completion of IntelliJ IDEA Kotlin plugin dose not work in this way. FragmentActivity's extension property show is not suggested as myDialog's members.

私は後者が好きです。 それっぽく "double context extension" パターンと名付けます。

I prefer the later. Plausibly I named this pattern "double context extension".

(Thank you for reading this to the end. Please point out my English errors to me.)