Perl日記

日々の知ったことのメモなどです。Perlは最近やってないです。

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()を使うべきだよなぁ。


僕はこう思う。

それでもバージョン上げた結果の不具合がこれくらいだった。
Perlの後方互換性すごい。