クソコードは読むな、動かせ
はじめに
この記事では、「クソコード」のバグに直面した際、なぜ実際に「動かす」ことが重要なのかに焦点を当てます。クソコードのバグ修正をする場合は、早期にコードリーディングをあきらめ、デバッガーを利用することでコードの流れを手に取るように理解し、問題の原因を素早く特定する方法について説明します。
クソコードの特徴
クソコードとは、理解しづらく、非効率的で、保守が困難なコードのことを指します。これには、不要な複雑さ、不適切な命名規則、繰り返しコード、過剰な依存関係などが含まれます。クソコードはプログラムの可読性と保守性を低下させ、バグの原因となります。そのため、単に読むだけでは不十分で、実際に動かして問題を解決するアプローチが必要です。
というかとてもひどいクソコードは人知を超えているので、素直な気持ちで読んでいると全く理解できないです。なので、早い段階でデバッガーを動かし何が起きているのかを早く掴むことが大事です。
フロントエンドとバックエンドのどちらでバグが起きているか
実際にデバッガーを使用する前にバグがフロントエンド、バックエンドのどれで発生しているのか原因を切り分けます。フロントエンドとバックエンドのどちらでバグが発生しているかを特定するためには、以下のステップに従って問題の原因を探ります。
-
API レスポンスの検証:
- まずは、API のレスポンスが正しいかどうかを確認します。これには、API エンドポイントへの直接的なリクエスト(例えば、Postman や curl を使用)が役立ちます。
- レスポンスのデータを検証して、期待される形式や内容であるかを確かめます。不足しているデータや形式の不整合がないかをチェックしましょう。
- ステータスコードも重要です。例えば、
200 OK
は成功を意味し、400
や500
シリーズのエラーはそれぞれクライアントサイドとサーバーサイドの問題を示しています。
-
ネットワークリクエストの監視:
- ブラウザの開発者ツールを使用してネットワークリクエストを監視します。これにより、フロントエンドからのリクエストが正しいエンドポイントに正確なパラメータと共に送信されているかを確認できます。
- レスポンスのタイミングやサイズ、それに伴うエラーも重要な情報源です。遅延や予期しないレスポンスサイズは、バックエンドの問題を示唆することがあります。
-
コンソールエラーのチェック:
- フロントエンドで JavaScript エラーが発生していないか、ブラウザのコンソールを確認します。これは、フロントエンド側の問題、特にスクリプトや UI のバグを見つけるのに有効です。
- コンソールに表示されるエラーメッセージやスタックトレースは、問題の原因を特定するための重要な手がかりを提供します。
-
API とのインターフェースの検証:
- フロントエンドのコードで API とのインターフェースが適切に設定されているかを検証します。これには、API リクエストを生成するコードの確認や、適切な HTTP メソッドとヘッダーが使用されているかの確認が含まれます。
- 誤ったエンドポイントや誤ったリクエストの構成は、予期しないレスポンスやエラーを引き起こす可能性があります。
-
データベースデータの検証:
- バックエンドで使用されているデータベースのデータを検証します。これは、データの不整合や誤った情報が問題の原因となっている場合に特に重要です。
- SQL クエリを使用して、データベース内の関連するテーブルやフィールドのデータを確認します。不適切なデータ、欠損している情報、または期待と異なるデータがないかを確認します。
- データベースのログを確認して、最近の変更や異常なパターンを探します。これにより、データに関連する問題が特定される可能性があります。
これらのステップを通じて、問題がフロントエンド側にあるのか、それともバックエンド側にあるのかを効果的に特定することができます。この情報を元に、より具体的なデバッグ手法を適用し、問題の解決に進むことが可能となります。
デバッガーの重要性
デバッガーとは
デバッガーは、プログラムの実行を制御し、コードの挙動を観察するツールです。ブレークポイントを設定してプログラムの実行を一時停止させ、変数の値やメモリ状態を検査することができます。デバッガーを使用することで、コードの問題点を効果的に特定し、解決することが可能になります。
デバッガーの利点
デバッガーは、コードの問題を視覚的に特定し、ステップバイステップで追跡することができるため、問題解決を迅速化します。また、プログラムの実行時にのみ現れる問題を発見するのに特に有用です。デバッガーを使うことで、単にコードを読むだけでは見逃されがちな問題を明らかにすることができます。
デバッガーを使った分析
二分探索で調べる
コードの問題を特定する際に、大規模なコードベースのどこに問題があるのかを特定するために二分探索の原理を用いることができます。ブレークポイントを設定し、コードの中間点でプログラムを一時停止させます。そこから、問題が前半部分にあるか後半部分にあるかを確認し、徐々に問題の範囲を狭めていきます。
最初と最後で調べる
デバッガーを使用して、コードの最初の部分と最後の部分でプログラムの状態を確認することで、問題が発生する前と後で何が変わったのかを把握します。これにより、問題の原因がどのような変更によって引き起こされたのかを理解するのに役立ちます。
呼び出しスタックを見る
エラーが発生した際の呼び出しスタックを見ることは、問題が発生したコンテキストを理解するのに非常に役立ちます。呼び出しスタックは、エラー発生時点で実行されていた関数の階層を示し、どの関数がどの関数を呼び出したかを明確にします。これにより、問題の原因となったコードの部分を迅速に特定することが可能になります。
条件付きブレークポイントの使用
条件付きブレークポイントを使用することで、特定の条件が満たされた場合にのみプログラムを一時停止させることができます。これは、問題が特定の条件下でのみ発生する場合に特に有効です。例えば、特定の変数が特定の値になった時にのみブレークポイントを動作させることができます。
変数の値追跡
特定の変数の値が取得できていない場合、その変数の値がセットされる箇所にブレークポイントを設定することが有効です。デバッガーを使用して、変数の値が変更されるタイミングと条件を正確に把握することができます。特に、高度なプログラミングテクニックやアノテーション(例えば、@getter など)を用いるよりも、シンプルなコードスタイルで変数のセットやゲットを行うことが、デバッガーを用いた解析においては明確で効果的な場合があります。このアプローチにより、コードの動作を容易に追跡し、問題の特定を容易にすることができます。
プログラムの前条件と後条件の確認
デバッガーを使用する際、特に重要なのが、プログラムの前条件と後条件を確認することです。プログラムや関数が呼び出される前に満たされるべき前条件(入力値の範囲、状態の制約など)と、実行後に期待される後条件(出力の状態、変更された変数の値など)を確認し、それらが適切に満たされているかを検証します。このステップにより、コードが仕様通りに動作しているかを確かめることができ、バグの特定と解決に大きく貢献します。
まとめ
デバッガーの使用は、クソコードの理解と問題解決において非常に強力なツールです。上記の方法を活用することで、複雑な問題に迅速かつ効果的に対応することができます。デバッガーの機能を十分に理解し、適切に使用することが、コードの問題を効率的に解決する鍵となります。
Discussion