ラバーダック・デバッグ:処理を説明して自分で矛盾を見つける

入門 | 12分 で読める | 2026.07.11

公式ドキュメント

ラバーダック・デバッグは、コードを誰かに順番に説明することで、自分の思い込みへ気づく方法です。相手は詳しい人でなくても構いません。

説明する順番

ラバーダックデバッグで処理の目的、入力、条件、値の変化、成功と失敗の出力を順に説明する図

  1. この処理の目的
  2. 入力がどこから来るか
  3. 各条件が何を判定するか
  4. 値がどう変わるか
  5. 成功時と失敗時の出力

「ここは当然こうなる」と説明を飛ばした場所に、未確認の前提が隠れます。

ボタンを押すとsubmitが発生する。
submitでformDataを作る。
ここでemailを取得するはず……取得コードがnameではなくidを見ている。

説明中に原因へ気づいても、最初からやり直す必要はありません。気づいた前提を確認します。

AIへ説明する時にも使える

AIへコードだけ貼る前に、自分で処理を説明してから質問文へ入れます。説明できない箇所が、確認してほしい範囲です。

説明できることは、暗記ではなく処理のつながりを理解している証拠になります。

ケーススタディ:検索結果が一件ずれる

商品検索で二ページ目の先頭商品が一ページ目の末尾と重複する場面を考えます。「ページングが壊れている」と要約するだけでは、説明の粒度が粗すぎます。入力したページ番号、一ページの件数、並び順、計算した開始位置、DBへ渡した値、返却件数を順番に声へ出します。「二ページ目なので開始位置は十件目。式はページ番号掛ける件数」と説明した時、ページ番号が一始まりなのにそのまま掛けている矛盾へ気づけます。

気づいた直後に式を書き換えず、一ページ目、二ページ目、最終ページの具体値を紙へ置きます。期待する開始位置と実際の値が初めて違う場所を確認し、そこだけを修正します。良い説明は「この変数は何を表すか」「その値をどこで観測したか」「条件が偽なら次にどこへ進むか」を含みます。悪い説明はコードを日本語へ読み替えるだけで、「ここで適切に処理する」のような未確認語を使います。

説明を止める判断

ラバーダックは万能ではありません。十五分説明しても最初の差が見つからない、外部APIや並行処理の実際の状態が必要、再現が不安定という場合は、説明を続けるより観測を増やします。ブレークポイント、Network、DBの問い合わせ記録、最小テストを使い、得た事実を新しい説明へ戻します。秘密情報を含むデータは、AIや共有文書へそのまま貼らず、構造を保った仮の値へ置き換えます。

効果を観測する

開始時刻、最初に説明できなかった箇所、採用した仮説、原因特定までの時間を短く記録します。修正後には、同じ説明をコードを見ずに再現し、正常入力と境界入力の結果を予測します。説明と実行結果が一致し、追加したテストが修正前に失敗して修正後に通れば、思いつきではなく原因へ到達したと判断できます。

毎回長い文章を作る必要はありません。入力、変換、分岐、出力を矢印で並べるだけでも十分です。ただし「たぶん」「自動的に」「なぜか」が出た場所には印を付けます。その言葉が残ったまま修正へ進むこと、実行結果を見ずに納得すること、複数箇所を同時に変えることが失敗条件です。

よくある誤解:コードの朗読ではない

行を上から日本語へ置き換えるだけでは、プログラムが満たすべき約束を検査できません。「この変数に1を足します」ではなく、「ページ番号は1始まりだが配列位置は0始まりなので、ここで1を引く必要がある」と、値の意味と変換理由を話します。説明中に「適切に」「いい感じに」が出た場所は、まだ処理を説明できていない場所です。

相手が人形である必要もありません。紙、空のIssue、音声メモでも、入力から出力まで省略せず話せれば同じ役割を果たします。ただしAIへ説明する場合、秘密値や顧客データを渡さず、AIの推測を観測済み事実として扱いません。

説明する対象具体的に口にする内容
入力型、単位、空値、境界値
状態変更前の値と所有者
分岐真になる例と偽になる例
反復開始、終了、各回で変わる値
出力呼び出し側が期待する契約
副作用DB、通信、画面、時刻への変更

デバッグ確認:具体値で処理を通す

不具合が出た入力を一つ選び、各行の直前と直後の値を紙へ書きます。分岐では採用した経路だけでなく、なぜ反対側へ行かなかったかも説明します。初めて期待と違う値が現れた行を見つけたら、そこで失敗テストを追加し修正します。

説明しても値が分からない箇所は、推測で埋めずデバッガやログへ切り替えます。外部APIの応答、競合する非同期処理、DBトランザクションは実測が必要です。ラバーダックは観測の代用品ではなく、どこを観測すべきか絞る方法です。

まとめ

ラバーダック・デバッグ:処理を説明して自分で矛盾を見つけるで大切なのは、用語を単独で暗記することではありません。期待、観測、差分、仮説、操作、結果を順に残し、テーマに合う証拠で判断します。小さく確認し、再現できる説明を残すことが、修正と学習の両方を次へつなげます。

参考リソース

説明で判明した事実と推測を分け、次に観測する値を一つ決めます。聞き手が答えを知っていても、説明者が自分の前提を発見する時間を奪わないことが重要です。

説明の粒度は対象に合わせます。関数内の計算なら変数一つずつ、サービス間障害なら要求、キュー、保存、通知という境界ごとに話します。細かすぎて全体の目的を失ったら一段上へ戻り、粗すぎて値が見えなければ一段下へ降ります。この往復により、「APIが変」のような大きすぎる主語を、特定の応答項目や時刻へ狭められます。

複数人で使う時、聞き手は途中で修正案を連発せず、説明者が置いた前提を質問します。「その配列は空になれるか」「この時点で認証済みと言える根拠は何か」「同じ処理が二回走ったらどうなるか」のような問いです。答えが資料に依存するなら、その場で公式仕様やテストを確認します。

不具合が直らなくても、入力範囲、再現しない条件、未確認の外部状態が整理されれば進展です。その記録を技術質問へ転用すれば、次の担当者は同じ探索を繰り返さずに済みます。逆に、説明後に何も記録せず偶然の再実行で直った場合は、解決済みにせず再発時の観測点を残します。

説明の台本を処理に合わせる

検索結果が一件ずれるなら、「利用者が2ページ目を選ぶ」「URLから文字列の2を読む」「数値へ変換する」「APIのoffsetへ変える」「DBがoffset件を飛ばす」「結果を描画する」と境界を並べます。各境界で具体値を置くと、ページ番号と配列位置の基準差が見えます。関係のないCSSや通信設定まで列挙しません。

非同期処理では時間も説明します。「要求Aを開始し、次に要求Bを開始し、Bが先に完了し、最後にAが古い結果を上書きする」のように順序を話します。コード行の順と完了順を混同していることが分かれば、取消や要求ID照合を検討できます。共有状態では、誰がいつ値を書けるかを加えます。

再帰では、基底条件、引数が小さくなる理由、戻り値の合成を具体例で追います。オブジェクト参照では、コピーしたのが値か参照かを図にします。型変換では"0"0falseを代入し、暗黙変換の結果を予想してから実行します。題材に合う言葉を選ぶことで、説明が一般論へ逃げません。

修正後は同じ説明を短くやり直します。新しい条件分岐を「例外処理を追加した」で済ませず、どの入力がどの戻り値になるか言えれば、修正理由がコードと一致しています。説明できない複雑さが残るなら、関数分割や名前の改善も候補です。

次に読む記事

← 一覧に戻る
PR
PR
PR
PR