perlの標準入力で文字コードを指定するときの foo.pl foo.txt と foo.pl < foo.txt の違い

知らんかった。


ex: utf8で書いたtextを読んで文字数(byte数ではなく)を数えたい。

  • foo.txt

4文字のファイル作る

$ echo -n ほげほげ > foo.txt

  • foo.pl

文字数数えて出力。

binmode STDIN, ':utf8';
while (<>) {
  print length $_, "\n";
}

リダイレクトで標準入力を指定する場合は、文字数とおり4を出力するけど、perlの引数で指定するとbyteになって(1文字3byte)12になった。

$ perl foo.pl < foo.txt 
4
$ perl foo.pl foo.txt 
12

基本的にどっちでも同じような動きするから気にしてなかったけど、'<'のリダイレクトを使う場合はシェルの機能として標準入力が渡されけど、引数で指定する場合は標準入力ではないから動作が違う?


こういうときはだいたいdankogai様のblogを探せばなんとかなるだろう、と思っていたらやっぱりあった。

use open ':utf8' というのを追加すればいいらしい。

use open ':utf8';
binmode STDIN, ':utf8';