2006 年 3 月 19 日 23 時 58 分

インタフェースの統一


このアーカイブは同期化されません。 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];
};



Copyright (c) 1994-2007 Project Loafer. All rights reserved.