ファイルの読み込みでハマった。
foreachとwhileの違いを初めて知った。

ソース


#!/usr/bin/perl

open($fp,"<","./hoge.txt");
$i=1;
$len;

foreach(<$fp>){
$len=length($_);
last if($i++==3);
print;
}
print"-Rewind-\n";
seek $fp,-$len,1;
foreach(<$fp>){
print;
}
close($fp);

print "======================\n";

open($fp,"<","hoge.txt");
$i=1;

while(<$fp>){
$len=length($_);
last if($i++==3);
print;
}
print"-Rewind-\n";
seek $fp,-$len,1;
while(<$fp>){
print;
}
close($fp);



読み込むファイルはこれ


1:Baird
2:TY
3:North Island
4:Shigakogen
5:Minami-Shinshu
6:Oraho
7:Umenishiki
8:Fujizakura
9:Yo-ho



ソースは前半と後半でほぼ同じ。foreachとwhileの違いだけ。
これを実行すると


1:Baird
2:TY
-Rewind-
zakura
9:Yo-ho
======================
1:Baird
2:TY
-Rewind-
3:North Island
4:Shigakogen
5:Minami-Shinshu
6:Oraho
7:Umenishiki
8:Fujizakura
9:Yo-ho


こうなった。

理由
foreachは全部読んでからループの中身を実行する。いつループを抜けても最後まで読んだことになってる。
whileは1行読む度にループの中身を実行する。よってループを途中で抜けると、ちゃんとと途中で止まっている。
この差が結果にでる。

3行目を読んで文字数数えてループを抜けるまでは同じ。
seekの時点で、foreachは現在地がファイル末尾。whileは3行目末尾。
だからforeachは3行目の文字数分を末尾から戻るから8行目の途中から続きを読んでいる。
whileは3行目の末尾まで読んだ状態で3行目の文字数分戻るから、3行目を再読み込みして継続している。

こんなこと知らなかった。新版Perl言語プログラミングレッスン入門編/ソフトバンククリエイティブ

¥2,916
Amazon.co.jp

初めてのPerl 第6版/オライリージャパン

¥3,888
Amazon.co.jp