Hatena::ブログ(Diary)

昨日知ったこと

お知らせ

ただいま、Fiddler2を使うとちょうどいいような仕事を探しています。

2010-02-23

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

golferPerl の偉い人には常識なんだろうけれど。現在の入力ファイル行番号 $. は、for ではカウントされない。while だとカウントされる。

[takeyuki@sunya ^]$ cal | perl -e 'print$..$_ for<>'
8      22010
8日 月 火 水 木 金 土
8    1  2  3  4  5  6
8 7  8  9 10 11 12 13
814 15 16 17 18 19 20
821 22 23 24 25 26 27
828
8
[takeyuki@sunya ~]$ cal | perl -e 'print$..$_ while<>'
1      22010
2日 月 火 水 木 金 土
3    1  2  3  4  5  6
4 7  8  9 10 11 12 13
514 15 16 17 18 19 20
621 22 23 24 25 26 27
728
8

for の場合、入力ストリーム全体の行数になっているように見えるけれど、これはどういうことだろう。

追記

コメントをいただいた。for(expr) の expr はリストコンテキストで評価され、while(expr) の expr はスカラコンテキストで評価される、と。<> をリストコンテキストで評価するとストリームを全部読んできて $/ で切った文字列のリストを作る、ということを知ったのも大きな収穫。for の例は次のコードと同じことだな。

[takeyuki@sunya ~]$ cal | perl -e '@x=<>;print $..$_ for@x'
8      22010
8日 月 火 水 木 金 土
8    1  2  3  4  5  6
8 7  8  9 10 11 12 13
814 15 16 17 18 19 20
821 22 23 24 25 26 27
828
8

gfxgfx 2010/02/23 11:34 こんにちは,gfxと申します。
for(expr)はexprをまずリストコンテキストで評価するので,ループが始まる前にストリームを読み切ってしまうのですね。
これに対してwhile(expr)はループを回すごとにexprをスカラーコンテキストで評価するので,ストリームを少しずつ読み込みます。
$.はストリームの状態に関連付けられた特殊変数なので,forだとループが始まる前に最終行になってしまいます。

unauunau 2010/02/23 11:48 コメント、ありがとうございます。
なるほど、意味的に for はリストを取り、while は条件式を取りますね。なるほど。少し賢くなりました。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/unau/20100223/1266890799
 
Connection: close