このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
Encode, Jcode, jcode.pl はそれぞれ呼び出し規則が異なる。
今日はそれを吸収する仕組みを作ろう。
クラスレベルでインタフェースを統一する場合、
ラッパークラスを作るのが一般的。(Adapter パターン)
今回は、変換用の関数を呼ぶだけなので、
同じ引数と戻り値を持つ関数を用意するだけでいい。
では、統一するインタフェースとして、
Encode::from_to を使うことにしよう。
この関数は、変換するデータ、
変換前の文字コード、変換後の文字コードの三つを取り、
戻り値として変換後のバイト数を返す。
失敗すると、undef を返す。
Jcode や jcode.pl は同じインタフェースを持つので、
同じように変換することができる。
これらの変換関数は、convert だ。
Encode::from_to との違いは、
最初の引数がリファレンスであること、
変換後の文字コード、変換前の文字コードの順であること、
最後に、文字コードの指定の名前が独特であることだ。
さて、では、Encode と同じ引数、戻り値を被せてみよう。
sub jcode_from_to {
# Encode と Jcode が使う名前の変更用。
my %jcode_map = (
'euc-jp' => 'euc',
'shift_jis' => 'sjis',
'iso-2022-jp' => 'jis',
'utf-8' => 'utf8',
'ucs-2' => 'ucs2', # 正式ではないが。
);
# 引数に名前をつける。
my $data = \$_[0]; # リファレンス
my $from = $jcode_map{$_[1]};
my $to = $jcode_map{$_[2]};
my $encoding = Jcode::convert($data, $to, $from);
# 戻り値が未定義なら失敗。
return undef if not defined $encoding;
# 戻り値が 'binary' でも失敗。
return undef if $encoding eq 'binary';
# 長さを返却。
length $_[0];
};