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

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

"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.)

AndroidでKotlin勉強会 @ Sansan で発表してきたよ〜 #Kotlin_Sansan

connpass.com

発表&企画・運営のお手伝いをして来ました。

昨年10月にSansanさんがKotlin勉強会を企画しているということで、 Kotlinエバンジェリストを自称している私に講演オファーがありました。 企画当初は、基調講演的にKotlinの紹介的な話をする予定でした。

が、偶然勉強会当日にJetBrains社KotlinチームAndroid担当の@yanex_ruさんが来日されているということでしたので*1、基調講演をお願いしたところ快諾していただけました。 @yanex_ruさんの日本語による発表、面白く、すごく勉強になりました!

企画・会場提供していただいたSansanさん、発表された方々、参加者のみなさま、本当にありがとうございました。 次回開催を楽しみに待っています。

私の発表資料

↓あとでフォロー記事書きます。

勉強会レポート

スライドや動画がまとまってるのでぜひご覧ください。

当日の様子

↓@yanex_ruさん発表の冒頭で、いきなり私が呼び出され、Kotlinティーポットをプレゼントしていただきました!ありがとうございます٩(๑>∀<๑)۶

↓申し込み数はピーク時で60人定員の中100人超という大盛況でした。

↓おまけ: おいしいもの食べながら@yanex_ruさんにいろんなお話を伺いました。

*1:しれっと勉強会に参加登録してて驚きました。

KotlinプラグインのREPLが便利になってた #ktac2015

Kotlin Advent Calendar 2015の6日目の記事です(急遽担当変更になりました)。 まだ12月6日の32時なのでギリ大丈夫!

昨日は@chibatchingさんのアプリからサーバまで全部Kotlinなお手軽サービス開発 でした。

Android Studio上でKotlinプラグインは1.0.0-beta-3595-IJ141-11で試してみました。 メニューバーから「Tools」→「Kotlin」から選べるアイテムの中に「Kotlin REPL」が追加されていました。

f:id:ngsw_taro:20151207074751p:plain

ここからREPLを起動すると、なんとモジュールの環境上で動きます。 そのモジュールに定義されているクラスや依存ライブラリが解決された上でコードを実行できるのです。

f:id:ngsw_taro:20151207075011p:plain

上の画像は、Apache Commons Langに依存しているモジュール上でREPLを使っている様子です。 StringUtilsFQCNで指定していますがインポートすることも可能です。

これでKotlin開発がさらに捗りますね! メソッド名とかの補完ができたら最高ですが、現時点ではできないようです。

明日はn_yunoueさんです。

Javaイベント #jjug_ccc でKotlinの発表してきたよ〜

でっかいJavaイベントであるJJUG CCC 2015 Fallで発表しました。運営もしました。パネルディスカッションのモデレータもしました。 パネルディスカッションは@maaya8585この記事のとおりです。 楽しかったです。またやりたい。

発表スライドはこちらです。