forでは$.はカウントされない

ちょっと違うので横から。

これはforの動作というより、式の評価コンテキストの問題。

forはその性質上、操作対象は配列になる:
for (<>) {
     ....
}

# 上記はこれと同等
my @lines = <>;
for(@lines) {
    ....
}
なので、<>も配列として評価されるべく*まず最初に*<>を最後まで読み切って、行区切りの配列を作ってからforに渡す。このときファイルハンドルを読み切っているので、当然 $.はファイル全体の行数になる。

これに対して、whiileは対象を毎ループ評価するので、1行ずつの読み込みになる。だから$.は行毎の値になる。B::Deparseを使うとちょっとわかるかも。
# こっちはちょっと正直わかりにくいとは思うけど・・・
daisuke@beefcake $ perl -MO=Deparse -e 'print $. . $_ for <>'
;
print $. . $_ foreach (<ARGV>);
-e syntax OK

# こちらでは $_ = という操作になっているので、1行毎読み込んでるのが
# はっきりわかる。
daisuke@beefcake $ perl -MO=Deparse -e 'print $. . $_ while <>'
print $. . $_ while defined($_ = <ARGV>);
-e syntax OK
というわけで、forが違うというよりはファイルハンドルをリストコンテキストで読み込んだ場合とスカラーコンテキストで読み込んだ場合の動作が違う、っていうのが正解。

トラックバック(0)

このブログ記事に対するトラックバックURL: http://mt.endeworks.jp/cgi-bin/mt-tb.cgi/2450

コメントする

筆者

daisuke - a.k.a. "lestrrat", Perl hacker at Livedoor Inc, Japan Perl Association 代表理事

このブログ記事について

このページは、Dが2010年2月23日 11:15に書いたブログ記事です。

ひとつ前のブログ記事は「@INCとuse」です。

次のブログ記事は「Plack/Starman Daemontools Run File With Complete Deploy Bundle」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.1