whileでファイルハンドルをループする時の暗黙の$_について
こんな記事をみつけた。
Perlプログラムをコンパクトに記述する方法 - builder by ZDNet Japan
短く書けてPerlってすげーんだよ的な記事でまぁそれはそれでいいんだけどこういう場合はデメリットもちゃんと説明すべきかと。
というのも上記記事にこういうコードがあったのです。
while (<STDIN>) { print $_; }
$_を使うことによって「while( $line =
whileでの暗黙の$_はローカル化されないのです。コレ超重要。
つまり、
$_ = 100; while ( <STDIN> ) { print $_; } print $_;
こう書くと$_に格納してた100が上書きされてしまうので、whileを抜けたあとに$_を参照しても100という値は消えてなくなっちゃうというわけです。
ちなみにforeachの場合は暗黙の$_がローカル化されるので問題ありません。
$_ = 100; my @array = qw/a b c d/; foreach (@array) { print $_; } print $_; # ちゃんと100と表示される
これは大きな違いです。暗黙の$_をforeachのノリでwhileでも使っちゃうと思わぬところでバグが出ます。
こういう挙動をするということを知ってて使うのと知らないで使うのとでは雲泥の差があります。
ちょっとしたプログラムを書く場合は僕も$_使ったりして短くさくっと書いたりしますが、ちゃんとしたプログラム書くときはやはり普通に変数で受け取って処理するのが吉です。
while ( my $line = <STDIN> ) { print $line; }
どうしてもwhileで$_を使いたい場合は、暗黙の$_を使わずに明示的にローカル化すれば一応安全に使えます。
while ( local $_ = <STDIN> ) { print $_; }
ってことでみんな$_の扱いには注意しようね!