アウトライナーを作っていたら連休が終わった
連休中はほぼ毎日6〜8時間くらいプログラミングをしていた。
仕事ではない。趣味のアウトラインプロセッサづくりである。
連休の様子
昼に起きて昼食を食べたあとのろのろとコードを書き始め、夕方に調理休憩を挟んだあと22時まで開発をする生活だった。妻氏は買ったばかりの自転車であちこち出かけているというのに、私は家に籠もってプログラミングである。食材調達でしか外に出ていない気がする。
ほんとうは部屋の片づけとゲームのゴールデンウィークにしたかった。でも、アウトラインプロセッサの実装量が思ったより多く、22時をすぎて「残業」をしていることもあった。
ダイソン球づくり
私はあまりゲームをしないのだが、例外が二つある。自動化されているスマホのゲーム、プリコネおよびブルアカと、自動化をするゲーム、factorioやDyson Sphere Programである。このところDyson Sphere Programで工場建設に勤しんでおり、連休にダイソン球の建設まで進めたかったのだ。なのに、アウトライナー開発に時間がとられてしまった。
アウトライナーの複雑さ
なんでこうなったのかというと、アウトライナーが思いのほか複雑なアプリケーションだったからだ。
当初、私は「アウトライナーとかただの入れ子構造TODOリストでしょ」と思っていた。しかし、実際にはテキストエディタだったのだ。
テキストエディタはそこらじゅうにある。VSCodeでもウェブアプリでも、さまざまなメモ帳アプリでも。ところが、テキストエディタのUI実装はけっこうややこしいのだ。
例えばEnterとBackspaceの挙動を考えてみる。
こういうアウトラインがあるときEnterを押したらどうなるか?どのくらいの実装が必要なのか。
ただ改行をするのではない。アウトライナーの場合は、子トピックにするかどうか、ひとつのトピックを分割するかどうか、いろいろ場合分けが必要になる。
実際のパターンは下図のとおりである。
さらに、BackspaceはEnterの逆の処理になっていないといけない。違和感があればすぐにユーザーが気づいて怒りだす。
このような細かい挙動の実装が山ほどあった。
先日「アウトライナーのデータ構造は配列でよい」という記事を書いた。あの方針はたしかに正しかったのだが、正しいデータ構造を使ってなおアウトライナーのUI実装は複雑だった。仕様が複雑なときはデータ構造を工夫しても場合分けの数は減らないのである。
アウトライナー開発に苦しんで連休が終わろうとしているのだが、幸いほとんどの機能は実装し終えている。あとは細かい挙動のバグ修正や、マイナー機能の追加だけである。とはいえ、楽ではないはず。UIはすぐに挙動のおかしさがわかるので、人間の目にかなうように気をつかって仕上げる必要があるのだ……。
でも、連休を投じる価値はあったと思う。違和感なく使えるレベルのアウトライナーがほぼ完成したし、何より難しいのが楽しかった。モバイルフロントエンド開発の経験はあるのだが、テキストエディタほど難しくはなかった。よい経験になったと思う。
自分で作ってみると、WorkFlowyが月4ドルで使えるのは安いな、と思った。こんなややこしい実装をメンテナンスしてくれているのだ。しかもサーバーの運用コストもかかっているはず。
contenteditable地獄
余談だが、WorkFlowyをはじめとする多くのウェブブラウザWYSIWYGはcontenteditable属性を使っている。
ところが、contenteditableは仕様レベルで曖昧さのある怪しい仕組みらしい。検索するとたくさんの悲鳴が見つかる。
これはヤバいだろうな、と判断して今回はcontenteditableを避けtextareaを採用した。
この制約により、編集しながらテキストのスタイルを変えることはできなくなるのだが、デバッグで地獄をみるよりはマシである。よっぽどテキストのスタイルを変えたかったら、Markdown-likeな文字装飾記号をパースして、フォーカスが外れたタイミングでスタイルを当てるつもりだ。
道具を伝家の宝刀にしてはいけない
鋼の包丁をもっている。よく切れて気持ちよく料理ができるのだが、錆びやすい。水分が天敵である。
なので、水気のないところに保管していた。ふつうは包丁立てに挿しておくものだが、空気中の湿気で錆びるのが嫌で、包丁に布を巻きひきだしに寝かせて保管していた。
もちろん使いにくい。ワンアクションで包丁をとりだせないので、せっかくのいい包丁をさしおいて、しょぼいペティナイフを使うことも多かった。
先日、切れ味がよいのに勿体ないなと思って、ふつうに包丁立てに立てることにした。錆が浮いたらすぐに磨けばよろしい。毎日使う道具なので錆が出てきたらすぐにわかる。クレンザーと錆消しゴムで磨くだけだ。大事なのは手入れである。
せっかくのいい道具が「伝家の宝刀」になっていたのだろう。大仰にしまい込んで使いにくい道具にしていた。よっぽどの事態にならない限り使われないのが「伝家の宝刀」である。しかし、道具は道具である。ふだんから使ってない道具をよいしょ、と出してきたところで道具は手に馴染まず、いい仕事はできないだろう。
私はコレクションとしてではなく、道具として包丁を買ったのだ。錆を恐れて祭り上げてはいけない。たとえいい道具であっても壊れることを臆せず、気軽に使えるようにしておかないといけない。
できごと
日記をふりかえったメモ。
- 美容院で髪を切った。自転車で数km移動しただけで疲れていた。体力がないことを自覚する。
- モルモット用トイレを洗って捨てた。どうせトイレの場所を覚えない種族なのでなくてもよい。スペースができて掃除しやすくなった。
- 5/1あたりに自律神経が悪くなってイライラしていたのだが、自覚したらよくなった。お灸と鍼で対処したおかげでもある。
- 千葉雅也氏のnoteがよかった。運動をひとつひとつコントロールせずに、大きな目的意識だけ持っておくことが書かれていた。たしかに自転車を漕ぐときに足の動かしかたなんて考えない。
- ただ、手書きとタイプの書き味の違いに関する考察はよくわからなかった。真似してATOKのライブ変換も導入したがいまいちしっくりこない。
- そういえば文章術の本を読み終わっていた。漢字の閉じ開きが大事、段落は短くという話があった。
- DSP(Dyson Sphere Progaram)をやっていて、ビジュアルプログラミングが苦手なのに気づいた。映像の情報量が多いと意識を持って目的を認識するのが難しくなる。また、アイコンを探すのも苦手だ。
- アファンタジアの特性だと思われる。
- DSPで潮汐ロック惑星を見つけ、そこに移住した。物流ステーションを使ったライン構築に挑戦する。あちこちでボトルネックが発生し右往左往した。
- ワイン常備を再開した。暑い季節にはおいしいので。
- まわりはビール派が多く釣られてビールを飲んでいた時期もあるが、やっぱりワインが合ってる気がする。
- 炭酸が苦手、酒に弱くて量が飲めないため。
- 社交ダンスの先生のトレーニングイベントに参加した。胸椎を柔らかくすれば万事解決することを知る。
- 団塊くらいの世代は戦争遂行世代への逆張り意識に富んでいるが、あれは伝統的な価値観の親世代と都市化が進んだ世代の対立なのかもしれないな、と思った。
- ソファでぼーっとして体力を回復するスキルを身につけた。
- 布団に行くのではなく、ソファで座ったまま休まるのがポイント。
- 頭が重くて考えられないのを体調不良だと思っていたが、たぶん副交感神経が活発化しているだけな気がする。
- 「なんでもVPSに詰めこめばいいじゃん」について考えたところ、運用コストが問題になるのは人件費が高い場合のみ、というこの世の真理に気づいてしまう。
- 久しぶりに製麺をした。麺帯までは順調だったのに、細麺を切ろうとしたらローラーが壊れてしまった。説明書をよく読むと細麺は高速で動かせと書かれていた。
- ローラーはあとで分解してなおした。
- なぜか徹夜をしてしまい騒然となる。眠れないから仕方ないと言ってDSPをしていたら5時だった。妻氏もなぜか徹夜をしていた。
- 翌日体調が終わった。
- 自分に合った運動とはなにか?を考えたところ、家の片付けと掃除が答えだと確信した。猛烈に片付けをして腰が少し痛くなる。
- 筋肉が増えた自分をみても嬉しくない、他人に勝ちたいわけでもない、頭を空っぽにして運動ができないため。それぞれ筋トレ、競技、ヨガが候補から落ちる。掃除とか整頓は得意。
- 日常的な運動はNEATと呼ばれるやつで、本当にそういう概念がある。