11.7 練習問題1
第11章[ファイルハンドルとファイルテスト]の練習問題1へ。
ユーザから入力ファイル名、出力ファイル名、サーチパターン、置き換え文字列を入力して貰う様なプログラムを書いてください。
はじめてのPerl P.199
まずは自作解答です。
#! /usr/local/bin/perl use strict; use warnings; #このプログラムの説明をユーザに伝える print "指定元ファイルから、サーチパターンにマッチした文字列を指定した文字列に置き換え、それを指定先のファイルに書き換えるプログラムです。\n"; #入力ファイルを入力 print "指定元ファイルのパスを入力してください。\n"; chomp(my $input_file = <STDIN>); #出力ファイルを入力 print "指定先ファイルのパスを入力してください。\n"; chomp(my $output_file = <STDIN>); #サーチパターンを入力 print "サーチしたい文字列を指定してください。\n"; chomp(my $search_pattern = <STDIN>); #置き換え文字列を入力 print "マッチした文字列に置き換えたい文字列を指定してください。\n"; chomp(my $substitute_pattern = <STDIN>); #入力用ファイルハンドラをopen open INPUT, "< $input_file" or die "cannot open the file! ($!)"; #出力用ファイルハンドラをopen open OUTPUT, ">$output_file" or die "cannot open the file! ($!)"; #while命令で1つずつ読み、置換する while(<INPUT>) { s/$search_pattern/$substitute_pattern/g; #変数$_に対して置換を行う print OUTPUT; #変数$_を出力ファイルに出力する } #ファイルハンドラをクローズする close INPUT; close OUTPUT;
下記のtes1.txtというファイルを用いて、
jkondo reikon naoya kawasaki onishi
このプログラムを実行してみます。
C:\Perl\hajip>perl hoge.pl 指定元ファイルから、サーチパターンにマッチした文字列を特定の文字列に置き換え、それを指定先のファイルに書き換えるプログラムです。 指定元ファイルのパスを入力してください。 tes1.txt 指定先ファイルのパスを入力してください。 tes2.txt 指定元ファイルの置き換えたい文字列を指定してください。 kon サーチパターンにマッチした文字列を、何に置き換えるか、文字列を入力してください。 KON C:\Perl\hajip>type tes2.txt jKONdo reiKON naoya kawasaki onishi
機能上の問題はなさそうですね。
さらに解答を見て、いけてなかった部分を箇条書きにしてみます。
- ユーザにメッセージを出力し、入力を求める部分はサブルーチン化する。
全部で4つも同じ機能を書いてますね。無駄。
- ファイルの指定が行われたら、すぐさまファイルハンドラをオープンする。
これによって、無効なファイル名だった場合の時間の無駄がなくなる、と。
(これについては、コメント欄でid:kidd-number5さんが言うように、ロックの問題が発生してしまう。ファイルが存在しなければdieするのが最良か。)
- 出力ファイルを上書きしてしまうのを防ぐために、ファイルテスト-eで判断する
それじゃあ書き直しと行きますか。
#! /usr/local/bin/perl use strict; use warnings; #入力受付サブルーチン sub get_input { print $_[0]; chomp(my $input = <STDIN>); return $input; } #このプログラムの説明をユーザに伝える print "指定元ファイルから、サーチパターンにマッチした文字列を指定した文字列に置き換え、それを指定先のファイルに書き換えるプログラムです。\n"; #入力ファイルを入力、即ファイルハンドラをオープンする my $input_file = get_input("指定元ファイルのパスを入力してください。\n"); open INPUT, $input_file or die "入力用ファイル '$input_file' を開けませんでした。 ($!)"; #出力ファイルを入力 my $output_file = get_input("指定先ファイルのパスを入力してください。\n追加書き込みしたいときは、パス名の最初に\">\"を入力してください。\n"); die "出力用ファイル '$output_file'は既に存在しています。\n" if -e $output_file; open OUTPUT, ">$output_file" or die "出力用ファイル '$output_file' を開けませんでした。 ($!)"; #サーチパターンを入力 my $search_pattern = get_input("サーチしたい文字列を指定してください。\n"); #置き換え文字列を入力 my $substitute_pattern = get_input("マッチした文字列に置き換えたい文字列を指定してください。\n"); #while命令で1つずつ読み、置換する while(<INPUT>) { s/$search_pattern/$substitute_pattern/g; #変数$_に対して置換を行う print OUTPUT; #変数$_を出力ファイルに出力する } #ファイルハンドラをクローズする close INPUT; close OUTPUT;
ところでこのソースコードはいくらなんでもコメント付けすぎでしょうか?
長期間の保守作業が必要な場合には、たくさんコメントを書くのが良いというのはわかりますが、コメントをつける加減がイマイチわからないのです。