Kotlinで湯婆婆を実装

こんにちは。

本記事は、@NemesisさんのJavaで[湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)という記事の何番か煎じです。
なおかつ、@nakashimaakioさんもKotlinで実装した[湯婆婆をAndroidアプリで実装する](https://qiita.com/nakashimaakio/items/679201be94018e0de9d7)という記事を投稿されており、ますますもって二番煎じの二番煎じというネスト状態です。

ですが、後者の記事はAndroidアプリにしたがゆえに、コンソール入出力アプリである前者と異なるので、レイアウトリソースファイル（activity_main.xml）も必要だったり`OnKeyListener`でイベント処理もしたりと、Android色が強く前に出ています。
※なお、私はAndroidアプリに挑戦されたことを非難しているのではなく、むしろAndroidアプリ大好きな私にとっては実にナイストライ！だと思っております。

そこで私は、同じくKotlin言語を用いますが、コンソール入出力アプリで挑戦してみました。
かつ、このアプリの要件としては、名前の入力が空白だった場合はちゃんとクラッシュ湯婆婆をしなければいけないという仕様も求められているようですので、そこも忠実に守りたいです。

# コード

こうなりました。

```kotlin:Yubaba.kt
import java.util.Random

fun main() {
    println("契約書だよ。そこに名前を書きな。")
    val name = readLine()
    println("フン。${name}というのかい。贅沢な名だねぇ。")
    val newNameIndex = Random().nextInt(name!!.length)
    val newName = name.substring(newNameIndex, newNameIndex + 1)
    println("今からお前の名前は${newName}だ。いいかい、${newName}だよ。分かったら返事をするんだ、${newName}!!");
}
```

実行結果はこちら。


```console:山田太郎
契約書だよ。そこに名前を書きな。
山田太郎
フン。山田太郎というのかい。贅沢な名だねぇ。
今からお前の名前は太だ。いいかい、太だよ。分かったら返事をするんだ、太!!
```

```console:無記入
契約書だよ。そこに名前を書きな。

フン。というのかい。贅沢な名だねぇ。
Exception in thread "main" java.lang.IllegalArgumentException: bound must be positive
	at java.base/java.util.Random.nextInt(Random.java:388)
	at sample.kotlin.chap01.YubabaKt.main(Yubaba.kt:9)
	at sample.kotlin.chap01.YubabaKt.main(Yubaba.kt)
```

ちゃんと`IllegalArgumentException`が発生しました。
エラーメッセージ「bound must be positive」のツッコミ箇所が`Random.nextInt`であることまでオリジナル記事と一緒です。

まあ、そりゃそうですね。KotlinはJavaと100%互換言語ですから。足並みがそろって当たり前ですね。
そういえば、湯婆婆には、双子の姉「銭婆」がいますね。湯婆婆がJavaなら、銭婆はKotlinかな。声優も両者とも夏木マリが担当した、と言うことで互換性あるし。だなんて無理やり映画にかこつけようとしてみましたが、Kotlinの方が後発なのに姉とはこれ如何に。ムチャしちゃいました。

## コードの解説

Javaでは`java.util.Scanner`を持ち出さなければなりませんでしたが、Kotlinは`readLine()`という標準関数があるのでラクですね。

それより、気になっていただきたいのが、「`!!`」演算子です。
[Kotlinの公式言語リファレンス](https://kotlinlang.org/docs/reference/null-safety.html#the--operator)によれば、この`!!`演算子は「NullPointerException愛好家向けだよ（for NPE-lovers）」と皮肉付きで説明されています。
[「Null Safty」](https://kotlinlang.org/docs/reference/null-safety.html)を標榜するKotlinとしては、この`!!`演算子は何ともむず痒い存在です。

それもこれも、`readLine()`関数の戻り値が`String?`型、つまりNullable（`null`かもしれないヨ）オブジェクトをリターンするからです。
`null`かもしれない変数だけど、俺はコイツは`null`ではないと信じたい!!といったカンジでしょうか。

上述で「`!!`演算子は何ともむず痒い存在」だとは言いましたが、逆に頼もしい存在でもあります。
そこさえ強行突破できちゃえば、以降は[「Smart Casts」](https://kotlinlang.org/docs/reference/null-safety.html#safe-casts)機能が働くので、次のステップの`val newName = name.substring(newNameIndex, newNameIndex + 1)`の「`name`」にはいちいち`!!`演算子（も、`?`も）を付けるのが不要となります。

でも、やっぱり`!!`演算子は嫌だなぁ...と思ったので、次のコードその２をご覧ください。

# コードその２

スコープ関数`let`を使いました。

```kotlin:Yubaba2.kt
import java.util.Random

fun main() {
    println("契約書だよ。そこに名前を書きな。")
    val name = readLine()
    println("フン。${name}というのかい。贅沢な名だねぇ。")
    val newNameIndex = name?.length?.let { Random().nextInt(it) }
    val newName = newNameIndex?.let { name.substring(it, newNameIndex + 1) }
    println("今からお前の名前は${newName}だ。いいかい、${newName}だよ。分かったら返事をするんだ、${newName}!!");
}
```

[「Safe Calls」](https://kotlinlang.org/docs/reference/null-safety.html#safe-calls)と呼ばれる`?.`演算子を用いまくってますし、Nullableな変数に立ち向かうときによく使われるスコープ関数`let`も用いています。
まるで、石橋を叩いて叩いて渡るような慎重さが顕著なコードになりました。

# 最後に

湯婆婆そのものを楽しむつもりだったんですが、`null`に対応することの方が大変だった、という感想です。
あの映画「千と千尋の神隠し」の世界には、`null`という概念がそもそも存在するのかな？と思いを馳せてみたら、

あ。

カオ**ナシ**？？？
確かにこいつは、厄介だ。