行番号を付けてファイルを表示するスクリプトを書きました。
open(IN, $ARGV[0]) || die; while(<IN>){ chomp; printf("%04d:%s\n", $., $_); } close(IN); 【結果】 $ perl number.pl Test.m 0001:#import <objc/Object.h> 0002:#import <stdio.h> 0003: 0004:@interface Test : Object 0005:{ 0006: int cnt; 0007:} 0008:@end 0009: 0010:@implementation Test 0011: - (void) init{ 0012: self->cnt = 0; 0013:} ... 以下省略 ...
ついでにheadの機能をつけてみました。whileの中に行数を絞るロジックを追加しています。
open(IN, $ARGV[0]) || die; while($. < $ARGV[1] && <IN>){ chomp; printf("%04d:%s\n", $., $_); } close(IN); 【結果】 $ perl number.pl Test.m 5 0001: 0002: 0003: 0004: 0005:
・・・あれ? 行の内容が表示されなくなってしまいました。なんでだろう?
perldocの和訳によると、$_が使われる場合についてこう書かれてます。
【以下の 2つは同値です:】
while (<>) {...} # equivalent only in while!
while (defined($_ = <>)) {...}【Perl が(あなたが使いたくなくても) $_ を仮定する場合がいくつかあります。】
が単独で while テストでテストされた場合の 結果を入れるデフォルトの場所。 while テスト以外ではこれは起こりません。
「単独で」が条件になっています。なので、whileの中に余計な条件文を足すと、このご利益は消えてしまうと言うわけです。
こうしてみると、perlって微妙な挙動が非常に難しいですねえ。