ChatGPTでプログラムデバックをしてみる ~プログラミング研究室~


 こんにちは!
 ナビゲータのEVEです。
オフィスワーク.jpg
 本日は、いままでChatGPTを用いてやると言っていた、デバックをやってみました。今から考えると、雛形1本作ってから、その雛形から横展開すべきでした。そんな後悔を今更しても仕方がないので、今後は、そうしたいと思います。

[デバック]
 一番気になるのは、4,000ステップ弱の文字クラスです。これに、致命的なエラーがあったら、かなりの修正がはいりそうです。
 ただ、4,000ステップのプログラムのデバックは、ChatGPTの入力制限にひっかかります。そのため、メソッドとそのメソッドを構成するコンストラクタ、メソッド、プロパティデストラクタを切り出して1つのクラスとしてデバックすることにしました。以下が、初めてデバックしたクラスです。
 一番簡単なメソッド、指定文字列検索メソッドをターゲットにクラスを作成し、ChatGPTにデバックを御願いしました。

<?php/**************************************************【クラス名 】文字列クラス*【製 造 者】EVE*【製造年月日】2023年12月16日*【更新年月日】*【リリース日】*【バージョン】*【 概 要 】* 文字列の基本的な操作を行う*************************************************/class stringClass {//プライベート変数定義private $priErrorMessage = ""; //エラーメッセージprivate $priBaseString; //編集対象文字列private $stringLen; //文字列長private $stringByte; //文字列バイト数/**************************************************【メソッド名】コンストラクタ*【 引 数 】* $strObject:編集対象文字列*【返 却 値】* 正常時:true* 異常時:false*【製 造 者】EVE*【製造年月日】2023年12月16日*【更新年月日】*【リリース日】*【バージョン】*【 概 要 】* 初期の処理を実施する*************************************************/public function __construct(string $strObject) { //編集対象文字列//引数をプライベート変数へ設定する//文字列長を取得する$this->stringLen = mb_strlen( $strObject );//文字列バイト数を取得する$this->stringByte = strlen( $strObject );//引数をプライベート変数として設定する$this->$priBaseString = $strObject; //編集対象文字列}/**************************************************【メソッド名】指定文字列検索メソッド*【 引 数 】* key:検索キー*【返 却 値】* 正常時:検索語文字列* 異常時:false*【製 造 者】EVE*【製造年月日】2024年1月24日*【更新年月日】*【リリース日】*【バージョン】0.1*【 概 要 】* Keyに基づき検索し、検索文字列以降の文字を取得し返却する*************************************************/public function metSerchKey( string $key ) { //検索キー//■変数定義$result = ""; //検索結果$cutString = ""; //編集文字列//■入力データチェック//エラーメッセージが設定されているかどうか判定するif ( $this->metCheckErrorMessage() === false ) {//返却値を設定し呼び出し元へ制御を移すreturn false;}//検索キーの設定の有無を判定するif ( $key == "" ) {//例外メッセージを格納する$this->metSetErrorMessage("検索キーが設定されていません。検索キーは入力必須項目です");//返却値を設定し呼び出し元へ制御を移すreturn false;}//■処理開始//検索文字列を取得する$this->priBaseString = stristr($this->priBaseString,$key);//文字列長を返却するreturn $this->priBaseString,;}/**************************************************【メソッド名】文字列長取得メソッド*【 引 数 】なし*【返 却 値】* 正常時:文字長* 異常時:false*【製 造 者】EVE*【製造年月日】2024年1月21日*【更新年月日】*【リリース日】*【バージョン】0.1*【 概 要 】* 文字列長を取得し返却する*************************************************/public function metGetStringLen() {//■入力データチェック//エラーメッセージが設定されているかどうか判定するif ( $this->metCheckErrorMessage() === false ) {//返却値を設定し呼び出し元へ制御を移すreturn false;}//■処理開始//文字列長を返却するreturn $this->stringLen;}/**************************************************【メソッド名】文字列バイト数取得メソッド*【 引 数 】なし*【返 却 値】* 正常時:文字バイト数* 異常時:false*【製 造 者】EVE*【製造年月日】2024年1月21日*【更新年月日】*【リリース日】*【バージョン】0.1*【 概 要 】* 文字列バイト数を取得し返却する*************************************************/public function metGetStringByte() {//■入力データチェック//エラーメッセージが設定されているかどうか判定するif ( $this->metCheckErrorMessage() === false ) {//返却値を設定し呼び出し元へ制御を移すreturn false;}//■処理開始//文字列バイト数を返却するreturn $this->stringByte;}/**************************************************【メソッド名】事前プログラムエラーチェックメソッド*【 引 数 】なし*【返 却 値】* 正常時:true* 異常時:false*【製 造 者】EVE*【製造年月日】2024年2月14日*【更新年月日】*【リリース日】*【バージョン】0.1*【 概 要 】* 本プログラム前にエラーが発生していた場合エラーを*返却する*************************************************/public function metCheckErrorMessage() {//■変数定義static $result = true; //処理結果//■入力データチェック//エラーメッセージが設定されているかどうか判定するif ( $this->metGetErrorMessage() != "" ) {//例外メッセージを格納する$this->metSetErrorMessage("処理前にすでにエラーになっています。");//処理結果にfalseを設定する$result = false;}//返却値を設定し呼び出し元へ制御を移すreturn $result;}/**************************************************【メソッド名】エラーメッセージ設定メソッド*【 引 数 】なし*【返 却 値】* 正常時:true* 異常時:false*【製 造 者】EVE*【製造年月日】2023年12月16日*【更新年月日】*【リリース日】*【バージョン】0.1*【 概 要 】* エラーメッセージを設定する*************************************************/public function metSetErrorMessage(string $errMsg) { //エラーメッセージ//エラーメッセージを設定し呼び出し元へ制御を移す$this->prierrorMessage = $errMsg;}/**************************************************【メソッド名】エラーメッセージ取得メソッド*【 引 数 】なし*【返 却 値】* 正常時:true* 異常時:false*【製 造 者】EVE*【製造年月日】2023年12月16日*【更新年月日】*【リリース日】*【バージョン】0.1*【 概 要 】* エラーメッセージを取得する*************************************************/public function metGetErrorMessage() {//エラーメッセージを設定し呼び出し元へ制御を移すreturn $this->prierrorMessage;}/**************************************************【メソッド名】デストラクタ*【 引 数 】なし*【返 却 値】なし*【製 造 者】EVE*【製造年月日】2023年12月16日*【更新年月日】*【リリース日】*【バージョン】*【 概 要 】* オブジェクトが消滅する場合の処理を定義する*************************************************/public function __destruct() {//使用パブリック変数を初期化する$this->priErrorMessage = ""; //エラーメッセージ$this->priBaseString = ""; //編集対象文字列$this->stringLen = ""; //文字列長$this->stringByte = ""; //文字列バイト数}}?>

以上のプログラムのデバックをお願いしたところ、以下のような回答がありました。

❶コンストラクタのプロパティへの代入
 $priBaseString プロパティへの代入時に $ を付けていません。また、プロパティ名が priBaseString であるべきところで、 String になっています。
❷metSerchKey メソッドの文字列検索処理
 stristr を使用していますが、これは検索文字列以降の文字列を取得するものではありません。また、 stristr の戻り値が正しいように使用されていません。
❸metSerchKey メソッドの戻り値
 コンマ , が余分についており、また正しい形式で戻り値を返していません。
❹metSetErrorMessage メソッドと metGetErrorMessage メソッド
 それぞれエラーメッセージを設定するメソッドと取得するメソッドですが、エラーメッセージのプロパティ名が誤っています。

以上の通り、いくつかバグを指摘してくれました。この検証により、ChatGPTをデバックに利用することは有効だと判断しました。
 なお、❷については、ヘッダの「検索文字列以降の文字を取得し返却する」という記述の間違いを指摘しています。正確には、検索文字列を取得し返却します。
 ❷の結果を見ると、コメントから正しいプログラムかどうかも判断してくれているようです。今後、プログラムテスト前には必ずChatGPTでデバックしたいと思います。
 ChatGPTにも分かるはずもないのですが、今回デバックしたことにより、プライベート変数の頭にpriがついていないなどの仕様的なバグやコメントの間違いに気づくことができました。

[今回の反省点]
 とりあえず、ChatGPTの以上の回答を見れば分かりますが、分かりずらい・・・。バグが細かい部分だったということもあるのですが、事細かに質問してやっと気づくことができました。
 以上の点については、規約を事前に知らせておく、どういう回答をしてほしいのか、事前に知らせておくなどの対応をしたいと思います。

[あとがき]
 ChatGPTにデバックをお願いしたものと、同じものを、BardCopilotにもお願いしたのですが、Bardは構造上の指摘も多数してくれました。今まで、ChatGPTにしかお願いしていませんでしたが、併用すれば、正しいプログラムを作ることができそうです。
 Bardについては、後日お話しします!ちなみに、Copilotは、このレベルのクラスでも文字数制限にひっかかり、デバックできませんでした。
 プログラマの多くは分かっているとは思いますが、これ業務でやった場合、情報流出という扱いになるかもしれません。もしやる場合は、上長に十分相談し、適切な対応をとってから実施してください。
 以前、私の知り合いで、業務で作った成果物を自宅へE-メールで送り、裁判沙汰になった人がいましたが、そうならないように気を付けてください。
 では、また!!!

コメント