Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
knitで学ぶKotlin入門の次 #Kotlin_Sansan
Search
Taro Nagasawa
March 25, 2016
Programming
3
2k
knitで学ぶKotlin入門の次 #Kotlin_Sansan
第2回Kotlin勉強会 @ Sansan (
http://connpass.com/event/27583/
)で発表したスライドです。
Taro Nagasawa
March 25, 2016
Tweet
Share
More Decks by Taro Nagasawa
See All by Taro Nagasawa
Android開発者のための Kotlin Multiplatform入門
ntaro
0
370
Kotlin 最新動向2022 #tfcon #techfeed
ntaro
1
2.1k
#Ubie 狂気の認知施策と選考設計
ntaro
13
12k
UbieにおけるサーバサイドKotlin活用事例
ntaro
1
1.1k
KotlinでSpring 完全理解ガイド #jsug
ntaro
6
3.3k
Kotlinでサーバサイドを始めよう!
ntaro
1
920
Androidからサーバーサイドまで!プログラミング言語 Kotlinの魅力 #devboost
ntaro
5
2.6k
Kotlin Contracts #m3kt
ntaro
4
3.8k
How_to_Test_Server-side_Kotlin.pdf
ntaro
1
430
Other Decks in Programming
See All in Programming
flutterkaigi_2024.pdf
kyoheig3
0
110
Jakarta EE meets AI
ivargrimstad
0
560
初めてDefinitelyTypedにPRを出した話
syumai
0
410
PHP でアセンブリ言語のように書く技術
memory1994
PRO
1
170
Streams APIとTCPフロー制御 / Web Streams API and TCP flow control
tasshi
2
350
watsonx.ai Dojo #4 生成AIを使ったアプリ開発、応用編
oniak3ibm
PRO
1
120
3rd party scriptでもReactを使いたい! Preact + Reactのハイブリッド開発
righttouch
PRO
1
600
型付き API リクエストを実現するいくつかの手法とその選択 / Typed API Request
euxn23
8
2.2k
Outline View in SwiftUI
1024jp
1
330
OSSで起業してもうすぐ10年 / Open Source Conference 2024 Shimane
furukawayasuto
0
100
Tauriでネイティブアプリを作りたい
tsucchinoko
0
370
Less waste, more joy, and a lot more green: How Quarkus makes Java better
hollycummins
0
100
Featured
See All Featured
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
44
2.2k
Adopting Sorbet at Scale
ufuk
73
9.1k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
169
50k
Why Our Code Smells
bkeepers
PRO
334
57k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
27
840
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
890
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
Code Review Best Practice
trishagee
64
17k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
109
49k
RailsConf 2023
tenderlove
29
900
Optimizing for Happiness
mojombo
376
70k
Typedesign – Prime Four
hannesfritz
40
2.4k
Transcript
knitで学ぶ Kotlin入門の次 2016-03-24 第2回Kotlin勉強会@Sansan 長澤 太郎 @ngsw_taro
自己紹介 • 長澤 太郎 たろーって呼んでね • プログラマー@エムスリー株式会社 ◦ Android, Kotlin,
Java, Scala, Rubyなど • Kotlinエバンジェリスト(JetBrains黙認) ◦ 日本Kotlinユーザグループ代表 ◦ Kotlin入門書 目下執筆中! • やすべえとディズニーが好き
1. knitの紹介
knitとは • JUnitの薄いラッパー • 1ヶ月くらい前につくった • 今すぐダウンロード github.com/ntaro/knit
なぜつくったか // JUnit assertThat(actual, `is`(expected))
なぜつくったか // JUnit assertThat(actual, `is`(expected)) ダサい
knitを使うと // knit actual.should be expected
やってることは単純 actual.should be expected assertThat(actual, `is`(expected))
2. knitの造り
構成要素を分解 actual.should be expected (actual.should).be(expected)
構成要素を分解 actual.should be expected (actual.should).be(expected) オブジェクトへの参照
構成要素を分解 actual.should be expected (actual.should).be(expected) メソッド呼び出し
構成要素を分解 actual.should be expected asserter .be(expected) オブジェクトへの参照 →インタフェース Asserter
Asserter interface Asserter<T> { val target: T infix fun not(matcher:
Matcher<in T>) infix fun be(expected: T) infix fun be(matcher: Matcher<in T>) infix fun be(block: () -> T) infix fun notBe(unexpected: T) infix fun notBe(matcher: Matcher<in T>) infix fun notBe(block: () -> T) }
Asserter interface Asserter<T> { val target: T infix fun not(matcher:
Matcher<in T>) infix fun be(expected: T) infix fun be(matcher: Matcher<in T>) infix fun be(block: () -> T) infix fun notBe(unexpected: T) infix fun notBe(matcher: Matcher<in T>) infix fun notBe(block: () -> T) }
Asserter interface Asserter<T> { val target: T infix fun not(matcher:
Matcher<in T>) infix fun be(expected: T) infix fun be(matcher: Matcher<in T>) infix fun be(block: () -> T) infix fun notBe(unexpected: T) infix fun notBe(matcher: Matcher<in T>) infix fun notBe(block: () -> T) } infix call
infix call asserter.be(expected) asserter be expected • メソッドを中置演算子っぽく呼び出せる • 標準ライブラリだと
and や or がinfix指定されている
Asserterオブジェクトの生成 actual.should be expected
Asserterオブジェクトの生成 actual.should be expected 任意の型のプロパティ
拡張プロパティ should val <T> T.should: Asserter<T> get() = AsserterImpl(this)
拡張プロパティ should val <T> T.should: Asserter<T> get() = AsserterImpl(this) 型パラメータ
拡張プロパティ should val <T> T.should: Asserter<T> get() = AsserterImpl(this) 拡張プロパティ
拡張プロパティ should val <T> T.should: Asserter<T> get() = AsserterImpl(this) 型
拡張プロパティ should val <T> T.should: Asserter<T> get() = AsserterImpl(this) Asserterの実装
オブジェクトを生成
他の表現も可能 fun <T> should(target: T): Asserter<T> = AsserterImpl(target) fun <T>
T.should(): Asserter<T> = AsserterImpl(this)
このコードを実現したいがため // 関数 should(actual) be expected // 拡張関数 actual.should() be
expected // 拡張プロパティ actual.should be expected
このコードを実現したいがため // 関数 疑問文みたいな語順 should(actual) be expected // 拡張関数 actual.should()
be expected // 拡張プロパティ actual.should be expected
このコードを実現したいがため // 関数 疑問文みたいな語順 should(actual) be expected // 拡張関数 カッコが邪魔
actual.should() be expected // 拡張プロパティ actual.should be expected
このコードを実現したいがため // 関数 疑問文みたいな語順 should(actual) be expected // 拡張関数 カッコが邪魔
actual.should() be expected // 拡張プロパティ 英語の文章としてまぁ自然 actual.should be expected
このコードを実現したいがため // 関数 疑問文みたいな語順 should(actual) be expected // 拡張関数 カッコが邪魔
actual.should() be expected // 拡張プロパティ 英語の文章としてまぁ自然 actual.should be expected ※DSLだから許される?
3. 小ネタ
トップレベルに関数やプロパティをおける package com.taroid.knit val <T> T.should: Asserter<T> get() = AsserterImpl(this)
val <T> (()->T).should: Asserter<T> get() = this().should
ファイル名どうするの問題 • クラスやインタフェースはJavaと同じ ◦ いわゆるpascal-case ◦ 例) AsserterImpl.kt • クラスがないファイルは?
◦ 特に決まりはないっぽい ◦ 試しにcamel-case ◦ 例) matcherAliases.kt ◦ IDEAさんならアイコンでわかる
識別子クォート、テストで便利だった class `be - expected` { @Test fun `does nothing
when target equals expected`() { sut be java.lang.String("Kotlin").toString() } @Test(expected = AssertionError::class) fun `throws error when target does not equal expected`() { sut be "kotlin" } }
Matcherを取るバージョン "knit".should(endWith("it"))
Matcherを取るバージョン "knit".should(endWith("it")) fun endWith(suffix: String): Matcher<String> = CoreMatchers.endsWith(suffix) 三単現のsを除く地味な工夫...
Matcherを取るバージョン "knit".should(endWith("it")) fun <T> T.should(matcher: Matcher(in T>) { assertThat(this, matcher)
} 拡張関数版 should (妥協)
Asserterにinvokeを持たせたかったが... "knit".should(endWith("it")) // NG ("knit".should)(endWith("it")) // OK "knit".should.invoke(endWith("it")) // OK
interface Asserter<T> { operator fun invoke(matcher: Matcher<in T>) ... なぜか型エラー
Thank you Enjoy Kotlin