湯婆婆ブームは過ぎたのは知ってるけどね。書きたい衝動を抑えられなかったんだよね。仕方ないね。
この記事で目指すこと
@Nemesis様の記事、Javaで湯婆婆を実装してみるの内容をJavascriptで、なおかつワンライナーで実装します。
なおワンライナーとは一行だけで書かれたコードのことを指しますが、Javascriptにおいて文の終わりを示すセミコロンは一切記述しないものとします。つまり、一文で書きます。
それと、最小文字数記録更新を狙っているわけではないのでMinify化はしません。
#とりあえずまずは普通に書く
いきなりコードを一行で書くのは無謀なので、まずは機能ごとに分解して普通に書いてみます。
##契約書
元の記事では、コンソールからの入力で契約書にサインを求めてきます。
ただ、Javascriptにはコンソールへの入力を受け付ける関数がありません。代わりにwindow.prompt()
でテキストボックスを含むダイアログを表示させ、入力された文字列を契約者の名前とします。
var name = prompt("契約書だよ。そこに名前を書きな。")
confirm("フン。"+name +"というのかい。贅沢な名だねぇ。")
##名前を奪う
入力された文字から乱数によって一文字を選んで抜き出し、新しい名前として与えます。
契約書へのサインをダイアログで行ったので、名前を与えるのもダイアログにします。
var num = Math.floor(Math.random() * name.length)//1から文字列の長さまでの整数の乱数を生成
var newName = name[num]//生成された乱数の場所にある文字を抽出
confirm("今からお前の名前は"+newName+"だ。いいかい、"+newName+"だよ。分かったら返事をするんだ、"+newName+"!!")
ところで、知識をお持ちの方は「なんでwindow.alert()
じゃなくてwindow.confirm()
使うんだ」と思われるかもしれません。わざとです。
後者の関数を使うと「はい」のほかに「キャンセル」という選択肢が増えるため、サインした名前が自分の名前であるという事実を「キャンセル」できたり、湯婆婆に名前を奪われるのを「キャンセル」できるわけです。
まぁキャンセルしたところで実行結果は変わらないんですがね
ワンライナー湯婆婆
ここまでが普通に実装した場合のJavascript湯婆婆です。
さて、この記事の目的は「ワンライナー湯婆婆を作る」ことなので、これらのコードを一文にします。
こうなりました:
((name) => {((_, newName) => {confirm("今からお前の名前は"+newName+"だ。いいかい、"+newName+"だよ。分かったら返事をするんだ、"+newName+"!!")}).call(this, confirm("フン。"+name +"というのかい。贅沢な名だねぇ。"), name[Math.floor(Math.random() * name.length)])}).call(this, prompt("契約書だよ。そこに名前を書きな。"))
アロー関数を繋げてcall()
したり、その引数内でconfilm
させたりしています。
これをコピーし、お使いのブラウザのコンソールにコピーして実行してみてください。ダイアログで湯婆婆とのやりとりが楽しめます。
#クラッシュ湯婆婆があったりなかったり
元の記事のコードでは、名前を空文字列とした場合に例外が発生、つまりクラッシュ湯婆婆という現象が発生します。このワンライナー湯婆婆の場合、サインをするときの行動によってクラッシュ湯婆婆が発生したりしなかったりします。
契約書に何も書き込まなかった場合、「フン。というのかい。...」のあとに「undefined」が名前として与えられます。一文字より長い名前を与えられるのは嬉しいですね。
そして、契約書への書き込みを「キャンセル」すると、名前が勝手にnullになった後にクラッシュ湯婆婆が発生します。
#おわり
以上、Javascriptでワンライナー湯婆婆を作ってみた話でした。
最後に、このコードは僕の貧弱な知識+Google検索で情報を手探りしながら書いたコードです。
もしもっと簡潔に書ける場合はコメントで教えていただけると嬉しいです!