tokuhirom's Blog

Perl5 において chomp() とはなにをするものか

えてして、プログラミングにおけるバグの発生源は、使い方をまちがえていることに起因するものも多い。 猫を電子レンジでかわかす人がいるように。


そもそも chomp() という組み込み関数はなぜ必要なのか。

Perl5 では、データを行単位で処理するということが重視されたインターフェイスになっている。これは一般的なテキスト処理の頻出パターンだからだ。

while (<>) {
    chomp;
    say if /foo/;
}

これは、入力データを行ごとにとりだし、改行をとりのぞき、/foo/ という正規表現にマッチする行だけを表示するというプログラムだ。 Perl5 を知っている人なら、だれもが簡単に理解できる。


ここで $/ という変数が問題となる。$/ は、行の区切りがはいっている特殊なグローバル変数で、awk でいうところの RS にあたるものだ。

この $/ を変更することにより「行」の区切りをかえることができる。


local $/;
my $x = "hoge\n";
chomp($x);

とした場合、行末の \n はとりのぞかれない。これは驚くには値しない。$/ を undef にするということは、Perl にたいして「改行コードなんてなかったんやー」と指示しているようなものなのだから。


つまり、Perl 5 の世界において <$fh>$/ までの入力をよみとり返す。chomp() は、文字列の末尾の $/ をとりのぞく関数。ということだ。

\n をとりのぞきたいことが明確なときには chomp() をつかわない方がいい。行志向のプログラムを書くときにだけ chomp() はつかわれるべきだ。


なお、2013年において、グローバル変数で行の概念をかえられる、なんてのはあまり意味がないしむしろ弊害が多い機能であることはいうまでもない。


http://d.hatena.ne.jp/gfx/20131116/1384587925 の内容、なんとなく適当にツイートしたやつがはられてたので、詳細にかいてみた。