perl 5.8.2
そろそろ多国語対応が安定してきたっぽい。
以下はソースをutf8で書いていてcp932の端末で動かして確認。
標準入出力の多国語対応
use utf8; binmode($_,":encoding(cp932)") for STDIN ,STDOUT ,STDERR; print STDERR "何か一行入力して:"; $input =; print STDOUT "入力したのは $input\n";
別の書き方。encodingモジュールはSTDERRには効かない。
use utf8; use encoding 'utf8',STDIN=>'cp932',STDOUT=>'cp932'; binmode(STDERR,":encoding(cp932)"); print STDERR "何か一行入力して:"; $input =; print STDOUT "入力したのは $input\n";
まずい例
use encoding 'utf8'; binmode(STDIN ,":encoding(cp932)"); use encoding 'utf8',STDIN=>'cp932'; binmode(STDIN ,":encoding(cp932)");
たとえ同じ文字コードを指定しても、二重に変換しておかしなことになるようだ。STDOUTも同様。
ソースコード中の日本語
use encoding; ではリテラル内部が多国語化される。
use utf8; は変数や関数の名前も多国語化できる。
use utf8; binmode($_,":encoding(cp932)") for STDIN ,STDOUT ,STDERR; $変数 = 'てすと'; print "$変数\n"; $変数 =~ s/す/正規表現/; print "$変数\n"; $perlにハァハァした人の数 =int rand 100000000; print "perlにハァハァした人の数→${perlにハァハァした人の数}人\n"; sub 日本語の関数{ print "日本語の関数名もおっけー\n"; } 日本語の関数();
まずい例:山カッコ演算子は多国語化されていない。
open(IN,"<:encoding(shift_jis)","cp932.txt")or die $!; print; open(my $ファイルハンドル,"<:encoding(cp932)","cp932.txt")or die $!; print <*$ファイルハンドル>; open(日本語のファイルハンドル,"<:encoding(cp932)","cp932.txt")or die $!; print <日本語のファイルハンドル>;
は以下を出力するか、もしくは出力時にエンコードに失敗する。
(ファイルの中味) GLOB(0x1a9513c) 日本語のファイルハンドル
ファイルハンドル自体は使えるので以下はうまく動く。
open(ファイルハンドル,"<:encoding(cp932)","cp932.txt")or die $!; use IO::Handle; print ファイルハンドル->getlines;
文字コードの自動判別
use utf8; binmode($_,":encoding(cp932)") for STDIN ,STDOUT ,STDERR; use open IO => ":bytes"; my $bytes = join( undef, <> ); use Encode::Guess; my $enc = guess_encoding( $bytes, qw/ cp932 euc-jp 7bit-jis / ); ref $enc or die "文字コード判別に失敗: $enc\n"; warn "encoding=",$enc->name,"\n"; use Encode; print decode($enc->name,$bytes),"\n";
<> の文字コード
perlには 引数に指定したファイル全ての中味もしくは標準入力を読む <> と
use open ARGV=> ...; とか書けると幸せなんだがな。