ナビゲータのEVEです。
昨日は、継承について考えましたが、本日は、その継承問題のきっかけになった、エラーメッセージ処理というか、エラー処理について考えてみたいと思います。
[try〜catch]
PHP の話なのですが、 オブジェクト指向言語 として製造しようとしたとき、 try〜catch を利用しようかどうか悩みます。以前は、直前のエラーを errno で取得し、エラーとしていたのですが、それが、PHP5.0から、try〜catchが実装されたため、オブジェクト指向言語で製造する場合は、try〜catchを利用することが多くなりました。ただ、今現在も、errnoは利用でき、オブジェクト指向言語でなくても、try〜catchを利用することは可能です。
っということで、エラーが発生した場合のロジックは、プログラムをどう作るのかということになります。
っで、今自分のプログラムを見直してみると、規則性がなく、try〜catchを利用する場合と利用しない場合があります。まっ、さすがに、errnoは利用はしていませんが・・・。但し、errnoは廃止される予定はございません。という現状で、エラーメッセージの仕様を考えるにあたり、頭を悩ませています。
ただ、もうすでに、クラスの80%製造済みなんですけれど・・・。今更悩むなって感じですか?
[Throwableインターフェース]
まずどうするのかと考える前に、PHP5.0に実装された Throwableインターフェース とはどんなインターフェースなのか調べてみました。
以下が、Throwableインターフェースの構造です。
Throwable
┣Exception
┃┣LogicException
┃┃┣BadFunctionCallException
┃┃┃┗BadMethodCallException
┃┃┣DomainException
┃┃┣InvalidArgumentException
┃┃┣LengthException
┃┃┗OutOfRangeException
┃┣RuntimeException
┃┃┣OutOfBoundsException
┃┃┣OverflowException
┃┃┣UnderflowException
┃┃┗UnexpectedValueException
┗Error
┣ArithmeticError
┃┗DivisionByZeroError
┣AssertionError
┣ParseError
┣TypeError
┗ValueError
以上のクラス群について、ChatGPTに解説をしてもらいましょう!
なお、PHP 7以降に導入された Throwable は、例外 (Exception) とエラー (Error) の共通の親インターフェース だそうです。抽象クラスだと思っていました(苦笑)
★Exception
用途
一般的な例外のベースクラスとして使用。
具体的な使用例
特定の目的で独自例外クラスを定義せず、汎用的なエラーを表す場合。
★RuntimeException
用途
実行時のロジックエラーを表す。
具体的な使用例
実行中の状態が不正な場合(例: 設定ファイルが読み込まれていない場合)。
★InvalidArgumentException
用途
メソッドや関数の引数が期待される形式や値ではない場合に使用。
具体的な使用例
引数が null であってはならない場合、または数値の範囲外の値が渡された場合。
★DomainException
用途
値が定義されたドメイン(範囲)に適合しない場合に使用。
具体的な使用例
引数が設定された業務上のルールに合わない場合(例: 日付が未来でなければならない)。
★LogicException
用途
プログラムのロジックに誤りがある場合に使用。
具体的な使用例
クラスの使用方法が設計上間違っている場合(例: 未初期化の状態でメソッドが呼び出された)。
★OutOfRangeException
用途
値が期待される範囲外である場合に使用。
具体的な使用例
配列のインデックスやパラメータが想定の範囲外である場合。
★OverflowException
用途
演算によって許容範囲を超えた場合に使用。
具体的な使用例
計算結果がシステムやアルゴリズムの上限を超えた場合(例: 値が INT_MAX を超えた)。
★UnderflowException
用途
演算が許容範囲の下限を超えた場合に使用。
具体的な使用例
スタックから値を取得しようとしたが空だった場合。
★LengthException
用途
長さが不適切な場合に使用。
具体的な使用例
文字列や配列の長さが指定された制約を満たさない場合(例: パスワードが短すぎる)。
★OutOfBoundsException
用途
無効なインデックスやキーが使用された場合に使用。
具体的な使用例
配列やコレクションに存在しないインデックスやキーを参照しようとした場合。
★BadFunctionCallException
用途
不正または存在しない関数を呼び出した場合に使用。
具体的な使用例
必要なコールバック関数が存在しない場合。
★BadMethodCallException
用途
不正または存在しないメソッドを呼び出した場合に使用。
具体的な使用例
クラスのメソッドが存在しない場合(例: 直接呼び出せないマジックメソッドを使用しようとした)。
★UnexpectedValueException
用途
値が期待に反して不正である場合に使用。
具体的な使用例
関数の戻り値が想定と異なる場合(例: ファイルの読み込みで数値を期待していたが文字列が返された)。
★TypeError
用途
データ型が期待と異なる場合に使用。
具体的な使用例
引数や戻り値の型が指定された型と一致しない場合(例: int 型を期待したが string が渡された)。
★DivisionByZeroError
用途
数値をゼロで割った場合に使用。
具体的な使用例
除算演算でゼロ除算が発生した場合。
★ParseError
用途
コードの構文エラーが発生した場合に使用(コンパイル時エラー)。
具体的な使用例
PHPスクリプトの文法が間違っている場合。
★Error
用途
プログラムの致命的なエラーを表す。
具体的な使用例
メモリ不足やシステムエラーなど、回復不能なエラー。
★Throwable
用途
すべての例外とエラーのベースインターフェース。
具体的な使用例
独自のエラーハンドリングを実装するための基底インターフェース。
[あとがき]
来年1月に仕様統一できているかどうか分かりませんが、思い立ったが吉日ということで、調査し、検討し、決めた内容については、少しずつ仕様として取り入れていきたいと考えています。
XPプログラミング とかでは、よくある話だとは聞いています。まっ、最終的に出来上がったモノがいいものであればいいのです。ただ、最初もっとよく考え、作れば良かったなとは思います。その一方で、初めてのオブジェクト指向言語の製造で、完ぺきな検討を終えてから作り出すのは無理かなとも考えています。
アメリカの経営者から聞いた話ですが、100%検討してから物事を開始するのは遅すぎる。ただ、検討しないのも問題はある。80%の検討を終えたら、取り掛かるのが最適だという話を聞いた記憶があります。
その言葉を念頭に振り返ると、まっ、ちょうどよかったかなって思っています。
では、また!