Paternity Leave: Month 3

Michael Lynch

育児休暇:3ヶ月目

一言でいうと

少しずつ仕事に復帰しています。

ハイライト

  • 新米の父親として、時間のやりくりが少し楽になってきました。
  • 伸び悩んで落ち込んでいたブログ記事が2本ありましたが、その後しっかり伸びてくれました。
  • 開発でスタックドdiffのワークフローを試してみました。gitの弱点を除けば気に入っています。

目標の自己採点

毎月のはじめに、その月に達成したいことを宣言しています。結果は次のとおりでした。

家族との時間を楽しむ

  • 結果:妻と息子との時間を楽しめました。
  • 評価:A

長時間まったく仕事をしていないように感じても、それは自分で選んでいることであり、時間の主導権は依然として自分にあるのだと意識すると、気持ちが楽になると気づきました。

仕事と家族の時間のちょうどいいバランスはまだ模索中ですが、状況は着実に良くなってきています。

Nixを使ったファズテストのチュートリアルを公開する

少しずつ仕事に復帰

この振り返りを書き始めるとき、仕事の時間が取れないという不安はすっかり昔のことのように感じていました。2ヶ月くらい前のことだろうと思っていたら、実は前回の振り返りで書いていたことで驚きました。

幸い、家族との時間配分についてはずいぶん気持ちが楽になっています。家族との時間をたっぷり楽しみつつ、これまで以上に多くの記事を公開できました。

影響した要因はいくつかあります。

息子が夜まとまって寝てくれるようになった

最初は一晩に3〜4回起きて、そのたびに60〜90分かけて授乳していましたが、今は起きる回数が2〜3回に減り、15〜60分でまた寝てくれるようになりました。

昨夜は通しで7時間45分も寝てくれて、とても嬉しかったです。

家族のサポートが増えた

息子が少し大きくなり、家族に来てもらって私たちがいなくても面倒を見てもらうことに抵抗がなくなってきました。今は週に5時間ほど手伝ってもらっていますが、家族はもっと手伝う気があるので、今後も増えていくと思います。

息子が昼寝している間に作業できる

息子は誰かに抱っこされていたり、抱っこ紐で胸の上にいるときの方が長く寝てくれるので、だいたい1日1〜3時間は息子を胸に乗せたまま作業しています。数時間まとまって妻が一人の時間を持てるので、妻の休憩にもなっています。

確保された作業時間を決めた

不規則なスケジュールで作業するのは難しいと感じています。妻が息子を見てくれている時間や、息子が胸の上で寝ている時間はたくさんあっても、いつ呼ばれてもおかしくないと思うと集中しづらいのです。

そこで妻が、毎日90分間は確実に集中できる時間を確保してくれることになりました。おかげで集中しやすくなりましたし、毎日その時間があるとわかっているので、高い集中力を要する作業はその時間に回すことができます。

ブログ記事に時間をかけすぎているだろうか?

以前は、難しいことを学ぶたびに、必ずそれを解説するブログ記事を書かなければならないという悪い癖がありました。

読者がごくわずかだったり、届ける手段がなかったりしても、すべての記事を最大限に磨き上げようとしていました。過去の例では、「Hiring Content Writers: A Guide for Small Businesses」(読者はいるものの、届ける手段がない)や、「Retrofitting Apps for Cloud Storage with Zero Code Changes」(非常にニッチで、私の特殊な用途以外では面白みがない)などがあります。

それらの記事を評価してくれた読者もいましたが、機会費用も考えなければなりません。それを書いていた時間で、もっと多くの読者に届いたり、全体としてより大きな価値を提供できたりする別の記事が書けたのではないか、ということです。

今ではもっと戦略的に考えるようになりました。一定数の読者に届きそうにないと思う記事は、書かないか、「Notes」コーナーに手早く簡単なバージョンとして書くようにしています。

「Using Nix to Fuzz Test a PDF Parser」

この記事にどれだけ時間を投資したかについては、複雑な気持ちです。

記事を書くことでNixやファズテストについて多くを学べましたが、思ったより時間がかかりました。最初は「数時間でサッとまとめられるだろう」と思っていたのに、結局20時間以上かかってしまいました。

LLM時代にソフトウェアのチュートリアルを書くのは、気が滅入ることでもあります。数年前までは、後から検索で見つけてもらえることで長期的なリターンがありました。今はニッチなチュートリアルを書いても、LLMに内容を吸い取られるだけで、読者はそれが自分の書いたものだということすら気づきません。

「Lessons from my First Exit」

この記事は最初からリスキーだとわかっていました。不利な要素がいくつかあったからです。

  • 事業売却の生々しい詳細についての話で、読者の99%は売却する予定がありません。
    • 売却についての前回の記事は反響がありましたが、あちらはストーリー仕立てだったので、自分で売却する気がない読者でも楽しめたのです。
  • とにかく長い。
    • 普段は1記事あたり読了時間10分を目安にしていますが、この記事は推定33分もかかります。
  • まともに伸びる可能性があるソーシャルメディアはHacker Newsくらいしかありませんでした。

Hacker Newsに投稿しましたが、フロントページにはまったく載りませんでした。

まだHacker Newsで伸びる可能性はあると思っていますが、たとえ完全に空振りに終わっても、書いてよかったと思っています。自分自身の買収について整理するのに役立ちましたし、もしまた事業を売却することがあれば参考になります。買収を経験した創業者や検討中の創業者からは、肯定的なフィードバックももらいました。

そして突然、記事が伸び始めた

上記を書いた後、Hackadayが私のNixファズテストのチュートリアルを取り上げてくれていたことに気づき、報われた気持ちになりました。

そして「Lessons from my First Exit」が空振りだったと書いた翌日、読者の誰かが再びHacker Newsに投稿してくれて、2位まで上がりました

それでも、最初の分析は正しかったと思っています。ファズテストの記事には時間をかけすぎましたが、TinyPilot売却についての記事への投資は適切でした。

スタックドdiffで大きな機能を実装する

ここ数週間、趣味のプログラミング時間のほとんどを、テレビ番組や映画のレビュー用ウェブアプリであるScreenJournalに費やしています。LetterboxdやGoodreadsのようなサービスですが、レビューは友人にだけ公開され、コードはオープンソースというのがコンセプトです。

ScreenJournalでユーザーが『Weird: The Al Yankovic Story』をレビューしているアニメーションデモ

ScreenJournal、私が作っているオープンソースのテレビ・映画レビュー用ウェブアプリ

当初からScreenJournalでは映画とテレビ番組の両方をサポートしたいと思っていましたが、シンプルな方からということでまず映画に対応しました。テレビ番組に対応できるよう汎化することは意図的にしませんでした。実現するかどうかわからなかったので、すでにある機能を最適化したかったのです。

10月にテレビ番組のレビュー機能を追加したので、レビュー対象は常に映画であるというコードベース内の多くの前提を修正する必要がありました。

全体の変更は最終的に2,000行に及び、一つのチェンジリストで理解するには少々扱いにくい量になりました。「チェンジリスト」という言葉を使っていますが、GitHubでいうプルリクエスト、GitLabでいうマージリクエストのようなものを指しています。

以前は、このような大きな変更に取り組むとき、機能が完成するまで壊れていたり未完成のままのフィーチャーブランチを用意していました。変更を直接そのブランチに入れるか、さらにそこからサブタスク用のブランチを切って、完了したらマージするというやり方です。

このやり方の問題は、フィーチャーブランチが巨大な変更の塊になってしまい、理解するには大きすぎることです。What Got DoneをFirestoreからSQLiteに移行したときがその例で、変更の中には多くのサブステップがあったのですが、すべてが混ざり合っているため個別に確認できません。

そこで今回のScreenJournalの変更では、別の方法を試しました。大きくて雑然としたフィーチャーブランチを維持する代わりに、スタックドdiffをやってみたのです。

スタックドdiffとは?

スタックドdiffとは、mainブランチがあり、大きな機能をマージしたいときに、その機能をABCといった変更に分割する手法です。mainからブランチを切ってAを作り、Aからブランチを切ってBを作る、というように積み重ねていきます。

GitHubはスタックドdiffをそれなりにサポートしていて、スタックがABCの場合、AからmainへのPR、次にBからAへのPRを作成します。AからmainへのPRをマージすると、BからAへのPRは自動的にBからmainへのPRへと更新されます。

テレビ番組レビューのフローで、ページごとにチェンジリストを作って作業を分割しました。

レビューを投稿する最初のステップは、レビューしたい作品を検索することです。以前は映画しかなかったので、テレビ番組対応の最初のステップとして、映画かテレビ番組かを選べるラジオボタンを追加しました。

ScreenJournalのタイトル検索画面に追加された、TVと映画を切り替えるラジオボタンのスクリーンショット

最初のタスクは、タイトル検索UIをテレビ番組対応に修正することでした。

次に必要だったのは、ユーザーがテレビ番組のシーズンを選べるようにすることでした。映画だけのときにはなかった機能なので、これも独立した変更として実装しました。

ScreenJournalのTVシーズン選択画面のスクリーンショット

2つ目のタスクは、レビューするテレビ番組のシーズンを選ぶためのウェブUIを実装することでした。

その後も同じように、フローの各段階ごとに新しいブランチを切り、別々のプルリクエストとして進めました。

この開発スタイルから得られた気づきをいくつか紹介します。

良かった点:スタックドdiffの方がモチベーションが上がる

スタックドdiffの良いところは、機能の各サブタスクがそれぞれ独立したチェンジリストになることです。

変更を小さな単位に分割することで、達成感や進捗感を得やすくなりました。大きな雑然としたブランチでサブタスクを終えても進捗が30%から35%にしかならないより、チェンジリストを一つ終えて100%完了したと感じられる方が満足感があります。

悪かった点:常に変更履歴を消さなければならない

スタックドdiffのワークフローで最も気に入らないのは、ソースの履歴を消してしまうことです。ソース管理の大きな利点を打ち消してしまいます。

スタックの前の方でやっておくべきだった変更に気づくたびに、git rebaseをしなければならず、履歴が書き換わります。そのためGitHubにforce pushする必要があり、チェンジリストには醜いforce-pushedの履歴が大量に残ります。

force-pushedの履歴が大量に並んだGitHubのPRのスクリーンショット

gitで頻繁にリベースすると、GitHubのチェンジリストに醜いforce-pushedの履歴が大量に残ります

すべての変更をまるで殺人事件の証拠のように厳密に残したい人もいるでしょうが、私はそこまで気にしません。ただ、ミスをしたときのために筋の通ったアンドゥ履歴は残しておきたいのです。force pushはリモート側のアンドゥ履歴を上書きしてしまい、ローカル側でも複雑な手順を踏まなければ復元できません。

良かった点:--update-refsでスタックドdiffのリベースが簡単になる

スタックドdiffのワークフローを試している途中で、gitの--update-refsフラグを知りました。これで複数のブランチを一度にリベースできます。

このテクニックのおかげでスタックドdiffが楽になりました。それまではスタックに4つブランチがあると、1つずつ順番にリベースしていて、うんざりするほど面倒だったからです。

悪かった点:--update-refsの後にpushするのが依然として面倒

ブランチがABCとある状態で、まとめてリベースすると、gitの出力は次のようになります。

$ git rebase master --update-refs
Successfully rebased and updated refs/heads/C.
Updated the following refs with --update-refs:
        refs/heads/A
        refs/heads/B

--update-refsでリベース自体は簡単になりますが、「さあ、リベースしたブランチをまとめてpushする」コマンドがありません。代わりにgitの出力をテキストエディタにコピーし、ブランチ名だけを抜き出して編集してから、git push origin A B C -fのようなコマンドに組み立て直さなければなりません。毎回作業の流れが途切れる面倒な手順です。

悪かった点:よく予期せぬgitの状態に陥る

正しい方法でリベースしているつもりでも、よく混乱する状態に陥りました。リベースしたのに、すでに解消したはずのコンフリクトをまた解消しろと言われるといった具合です。

コミットをsquashしてから再度リベースすることで回避しましたが、これも履歴を書き換えるのでミスを元に戻しづらくなります。コードを書くことよりも、どうやってgitにうまく謝るかを考えるのに頭を使ってしまうのが煩わしかったです。

jujutsuを試してみるべきかもしれない

jujutsuという新しいバージョン管理システムの話題をよく見かけるようになりました。Googleでも標準になりつつあるそうです。

数ヶ月前には試してみようかと考えて、「まあgitで十分だし、新しいおもちゃを追いかける必要はないか」と思っていました。でも今回gitのリベースで手こずって、gitの不便さを当たり前のこととして受け入れてきたのだと気づきました。

Steve Klabnik氏のチュートリアルをざっと読んだところ、jujutsuはスタックドdiffや複数ブランチの同時リベースをgitよりうまくサポートしているようです。

おすすめ

「Why I still blog after 15 years」 by Jonas Hietala

このブログについての記事にはとても共感しました。Jonasさんのサイトをさらに見ていくうちに、「この人はスウェーデン版の自分だな」と思いました。私の文章を楽しんでいただけるなら、彼の文章もきっと気に入ると思います。

「Notes on Ukraine」 by Matt Lakeman

先週Mattさんのブログを見つけたのですが、それ以来毎日のように「この人は何者なんだろう」と考えています。

Mattさんはあまり人気のない渡航先に10日ほど滞在し、その国についてのブログ記事を公開しています。ただの旅行はがきのような記事ではなく、その国の歴史を何時間もかけて調べ、現地の人々と対話した上で書かれた、中編小説ほどの長さの記事です。

さらに、Mattさんはインターネット上の別の場所でdormin111というユーザー名で長い投稿歴があることもわかりました。例えば映画『The Disaster Artist』についての詳細な分析などがあります。

彼のすべての仕事で最も驚くのは、そこに何の裏もなさそうなことです。これだけ執筆に力を入れている人を見ると、たいていはSubstackや有料講座などで稼いでいて、無料記事はロスリーダーなのだろうと考えるのが普通です。しかしLakemanさんの作品からは、そうした狙いや金銭的な動機がまったく見当たりません。ただひたすら深く考え、自分の思考を共有することが好きなだけのように見えます。

話をウクライナの記事に戻すと、てっきり戦争前に訪れたのだろうと思っていましたが、実際には開戦から2ヶ月後に訪れ、前線から数マイルの場所で兵士や民間人にインタビューしていました。職業的なジャーナリストではない人物が、ウクライナで多様な人々に直接取材して伝える戦争のカバレッジとして興味深く感じました。従来のメディアで見てきたどんなものよりも、 authenticで個人的な視点で状況を捉えているように思います。

Cyberpunk 2077(ゲーム)

私はあまりゲームをしません。年に1本新しいゲームを買って、飽きるまで5〜25時間ほど数日かけて遊ぶ程度です。このゲームはすでに25時間ほど遊んでいますが、まだ楽しめています。

その奥深さには驚かされます。25時間も遊んだのに、まだゲーム全体の5%くらいしか探索できていないと思います。現代のゲームの世界の広大さには驚かされます。

普段はゲームのストーリーはあまり気にせず、退屈な説明を延々と見せられるとイライラするのですが、Cyberpunkは数少ない、ストーリーをしっかり追いたいと思えるゲームです。そしてキアヌ・リーブスが主要な役で出演するほど声優に力を入れているのもすごいと思います。

Detroiters(テレビ番組)

この番組のことは聞いたことがありましたが、名前がどうも見る気をそいでいました。登場人物がデトロイトに住んでいることが最大の特徴の番組?つまらなさそうだと思っていました。

そしてこのクリップを見て、素晴らしい出演者が出ていることや、そのトーンがI Think You Should Leaveを少しだけ地に足をつけたシットコム版のような感じだと気づきました。シーズン1を見終えたところですが、とても面白かったです。

気を失ったジェイソン・サダイキスの前でチップスを食べるティム・ロビンソンとサム・リチャードソンが映る『Detroiters』の一場面

DetroitersI Think You Should Leaveを少しだけ地に足をつけたシットコム版のような作品です。

まとめ

何ができたか?

学んだこと

  • スタックドdiffは大規模な変更に適したワークフローですが、gitのサポートはあまり良くありません。
  • ブログ記事への投資は、期待されるリターンに見合ったものにすること。
    • 学んだことをすべて記録したい気持ちはありますが、ブログを経済的に持続可能にするためには、長文記事の多くが有料プロジェクトに興味を持ってくれそうな読者を引きつける必要があります。

来月の目標

原文は Michael Lynch により に公開されました。

この記事は「muse-spark-1.2-contributor」を使用して翻訳されました。