ポイント1: ファイルの入出力の成功をチェック
さてこのサンプルプログラムはうまく動きそうなので、最近元気の無い同僚の鈴木さんに、励ましのために送ってみましょう。鈴木さんはこんな風に実行しました。
% perl prog.pl 笑う長さを指定して下さい(数字): 20 (エンター) 保存するファイル名を指定して下さい(半角英数字): present/result.txt (エンター)するとどうでしょう。
以下のように余計な1行も表示されてしまいました。また、書き出したはずの result.txt も見当たりません。
わーっはっはははははははははは。わーっはっはははははははははは。 print() on closed filehandle $fh at prog.pl line 27, <STDIN> line 2.サンプルプログラムの 27行目にある print のあたりが問題のようですが、どうやら $fh がファイルハンドル(※1)として機能していないようですね。その直前のopenがうまく行っていないようです。
※1 ファイルハンドルやファイルの読み書きについての詳細は「Perl でファイルの中身を変更する」をご覧下さい。
【ポイント1】ファイルの入出力は必ずチェック
このように、ファイルの入出力はエラーが出やすい箇所ですので、ファイルの open は入力の時も出力の時も、必ず成功したかをチェックして下さい。
プログラムのこの部分は以下のように変更します。
サンプルプログラム: ファイルの入出力のチェック追加後
#ファイルにも保存 my $fh; open ($fh, '>:encoding(utf8)', $outfile) or die "指定したファイルが開けませんでした。実行を中止します。\nプログラムからのエラーメッセージは以下の通りです。\n$!" ; print $fh $laughter; close ($fh);変更後のプログラムを実行してみると、以下のようになりました。
% perl prog.pl 笑う長さを指定して下さい(数字): 20 保存するファイル名を指定して下さい(半角英数字): present/result.txt わーっはっはははははははははは。わーっはっはははははははははは。 指定したファイルが開けませんでした。実行を中止します。 プログラムからのエラーメッセージは以下の通りです。 No such file or directory at prog.pl line 26, <STDIN> line 2.
「じゃあどうしろ」というところまではこの段階では表示できないのですが、とにかく正常に処理ができないのでプログラムの実行が中止された事は分かります。
鈴木さんが穏やかな人なら、怒らずエラーが出たよと教えてくれるでしょう。
実はこの場合のエラーの原因はファイル名で指定した「present/」というディレクトリが無い事なのですが、プログラム上、どう対処するべきかは状況によって違います。指定されたディレクトリを作ってしまってもいいですし、逆にディレクトリを含む指定を許可しない、という選択肢もあります。
次のポイントは、この指定内容のチェックです。
>次は: ポイント2 外から来た値の汚染チェック