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
2.1k
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
780
Kotlin 最新動向2022 #tfcon #techfeed
ntaro
1
2.3k
#Ubie 狂気の認知施策と選考設計
ntaro
13
13k
UbieにおけるサーバサイドKotlin活用事例
ntaro
1
1.1k
KotlinでSpring 完全理解ガイド #jsug
ntaro
6
3.5k
Kotlinでサーバサイドを始めよう!
ntaro
1
1k
Androidからサーバーサイドまで!プログラミング言語 Kotlinの魅力 #devboost
ntaro
5
2.8k
Kotlin Contracts #m3kt
ntaro
4
4.2k
How_to_Test_Server-side_Kotlin.pdf
ntaro
1
520
Other Decks in Programming
See All in Programming
(Extension DC 2025) Actor境界を越える技術
teamhimeh
1
230
猫と暮らすネットワークカメラ生活🐈 ~Vision frameworkでペットを愛でよう~ / iOSDC Japan 2025
yutailang0119
0
220
CSC305 Lecture 02
javiergs
PRO
1
260
プロダクト開発をAI 1stに変革する〜SaaS is dead時代で生き残るために〜 / AI 1st Product Development
kobakei
0
490
私達はmodernize packageに夢を見るか feat. go/analysis, go/ast / Go Conference 2025
kaorumuta
2
490
非同期jobをtransaction内で 呼ぶなよ!絶対に呼ぶなよ!
alstrocrack
0
540
Чего вы не знали о строках в Python – Василий Рябов, PythoNN
sobolevn
0
160
LLMとPlaywright/reg-suitを活用した jQueryリファクタリングの実際
kinocoboy2
4
670
Catch Up: Go Style Guide Update
andpad
0
180
Introducing ReActionView: A new ActionView-Compatible ERB Engine @ Kaigi on Rails 2025, Tokyo, Japan
marcoroth
3
920
Go Conference 2025: Goで体感するMultipath TCP ― Go 1.24 時代の MPTCP Listener を理解する
takehaya
7
1.6k
育てるアーキテクチャ:戦い抜くPythonマイクロサービスの設計と進化戦略
fujidomoe
1
150
Featured
See All Featured
The Language of Interfaces
destraynor
162
25k
jQuery: Nuts, Bolts and Bling
dougneiner
64
7.9k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
132
19k
Making Projects Easy
brettharned
119
6.4k
How to Think Like a Performance Engineer
csswizardry
27
2k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.5k
Designing for humans not robots
tammielis
254
25k
Git: the NoSQL Database
bkeepers
PRO
431
66k
What's in a price? How to price your products and services
michaelherold
246
12k
Gamification - CAS2011
davidbonilla
81
5.5k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
657
61k
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