グッドデザイン賞を受賞したウォーターサーバー >>

配列@arrayからファイル名を読み取り、その中身を順次解析し、すべて解析し終わると@arrayの先頭に戻り同じ動作を行うコードなのですが、やたらとネストが増えすぎてしまい困っています。一応、サブルーチンを複数作っても見たのですがどうもスッキリしませんでした。
もう少し良いコードに改良、ご指導して頂けないでしょうか?


$| = 1;
my @array = ("1.txt","2.txt","3.txt");
for(;;){
for my $line (@array){
open(F,"$line");
my @f = <F>;
close F;
for my $line2 (@f){
if($line2 =~ m/test/) {
print $line2;
}else{
print "err\n";
}
}
sleep 1;
}
}

因みに、上記が最終ではなく、最終的には下記のようにしたい(@array部分を外部list.txtにする)のですがネストが増えてしましまい自分でも何を書いているのかよく分からなくなってしまいます。
$| = 1;
for(;;){
my $file = "list.txt";
open(F,"$file");
my @array = <F>;
close F;
chomp @array;
for my $line (@array){
open(F,"$line");
my @f = <F>;
close F;
for my $line2 (@f){
if($line2 =~ m/test/) {
print $line2;
}else{
print "err\n";
}
}
sleep 1;
}
}
__END__
----list.txt-----
1.txt
2.txt
3.txt
a.txt
b.txt
c.txt
-----------------

---1.txt---
test
text
taxt
test1
ttet
-----------

A 回答 (3件)

私も、自分用に捨てプログラム作るときは、コメントは少ないし、変数も$a,$b,$c...みたいな感じになります。


後から使い回そうとしたとき、perltidyにはよくお世話になります。

perltidyは結構高機能です。
例えば、 -csc オプションを付けると、ループ終わりの } に、その対応する { がわかるようなコメントが追加されます。
今回の場合は「ネストしてループ構造がよくわからない」ということですが、このコメントで大分わかりやすくなります。
他にもいろんなオプションがあるので、試してはどうでしょうか?

例) perltidy -csc -ce -bbb -lbl=1

$| = 1;
for ( ; ; ) {
  my $file = "list.txt";
  open( F, "$file" );
  my @array = <F>;
  close F;
  chomp @array;

  for my $line (@array) {
    open( F, "$line" );
    my @f = <F>;
    close F;

    for my $line2 (@f) {
      if ( $line2 =~ m/test/ ) {
        print $line2;
      } else {
        print "err\n";
      }
    } ## end for my $line2 (@f)
    sleep 1;
  } ## end for my $line (@array)
} ## end for ( ; ; )
    • good
    • 0
この回答へのお礼

perltidyにこんな機能があったのですか。全く知りませんでした。是非活用させて頂きます!

お礼日時:2016/12/27 22:36

現状でもそんなに複雑ではないので、あとは、名前の付け方とか改行とかコメントとかじゃないですかね。



$| = 1;
for(;;){

#listファイルから対象ファイル一覧を取得する
my $listfilename = "list.txt";
open(FP0,'<', $listfilename );
my @filelist = <FP0>;
close FP0;
chomp @filelist;

#全ファイルを処理する
for my $filename(@filelist){

#指定したファイルを読み込む
open(FP,'<',$filename);
my @lines = <FP>;
close FP;

#読み込んだファイルの中を確認する
for my $line (@lines){
if($line =~ m/test/) {
print $line;
}else{
print "err\n";
}
}

sleep 1;
} ## for my $filename(@filelist)
} ## for(;;)
    • good
    • 0
この回答へのお礼

ありがとうございます。自分用に作った場合、コメントアウト無しで作ることが多いです。それでも見直す事もあり、コメントアウトがあると非常に分かりやすくいいですね。

お礼日時:2016/12/25 19:00

インデントがきちんとしていれば、今のままでも、十分わかりやすいとは思います。


このgooのサイトはインデントが投稿時、崩れるので、元のがきちんとしている前提ですが・・・
とりあえず、サブルーチンを呼び出す形式に変えてみました。
現行のソースより行数は、多少増えています。
-----------------------------------
$| = 1;
for(;;){
sub1("list.txt")
}
sub sub1{
open(F1,$_[0]) or die "open error [$_[0]] $!";
while(<F1>){
chomp $_;
sub2($_);
sleep 1;
}
close F1;
}
sub sub2{
open(F2,$_[0]) or die "open error [$_[0]] $!";
while(<F2>){
if ($_ =~ m/test/){
print $_;
}else{
print "err\n";
}
}
close F2;
}
-----------------------------------------------------
    • good
    • 0
この回答へのお礼

ありがとうございます。
見やすくなりましたね。また、openハンドルをそのまま読ませる方がスッキリして良いですね。
インデントについては普段perltidyで整形しています。

お礼日時:2016/12/24 17:15

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


人気Q&Aランキング