Perl5.8.5から5.14.2にしたら文字化けした話
RHEL4のサポート期間が延長なしだと今日で最後。
Red Hat Enterprise Linux - Wikipedia
標準のPerlのバージョンは5.8.5。
というわけで先日RHEL5にすると同時に5.14.2にしてやるぜ!、と意気込んでperlbrewで入れたら(RHEL5のデフォはPerl5.8.8)、既存のシステムで文字化けした。
実際に文字化けしたのは、Encode.pmのdecode_utf8()を使用している箇所。
Perl5.8.5のEncode.pmのバージョンは2.01、Perl5.14.2の方は2.42_01だった。
めっちゃちがうな!
あまり深追いしなかったけれど、2.01のPP版のdecode_utf8は以下のコードだった。
sub decode_utf8($;$) { my ($str, $check) = @_; if ($check){ return decode("utf8", $str, $check); }else{ return undef unless utf8::decode($str); return $str; } }
あー単純にdecode("utf8", $str)のエイリアスみたいな感じかーと思って、2.42_01の方見たらだいぶ変わっていた。
sub decode_utf8($;$) { my ( $octets, $check ) = @_; return $octets if is_utf8($octets); return undef unless defined $octets; $octets .= '' if ref $octets; $check ||= 0; $utf8enc ||= find_encoding('utf8'); my $string = $utf8enc->decode( $octets, $check ); $_[0] = $octets if $check and !ref $check and !( $check & LEAVE_SRC() ); return $string; }
めっちゃちがうな!
404 Blog Not Found:#perl - utf8::decode()ではなくEncode::decode_utf8()を使うべき理由
こちらによると、不正なUTF-8が\x{fffd}で置き換えられるらしい。
あと良く見たら1個目の引数が書き換えられる場合もあるようだ。(サブルーチンの下から2行目)
この辺の理由かなー文字化けしたのは。
というのを頭に入れつつ、一度decode_utf8($str)をdecode("utf8"=>$str)にしたら文字化けしなくなったので、見ているところは合っていたのだと思う。
時間に余裕があんまりないので、今回はこれで凌ぐとしても、隙を見てdecode_utf8()を使うべきだよなぁ。