Jcode::CP932を作らなくても平気な気がしてきましたよ。

Jcode::CP932を作らなくても平気な気がしてきましたよ。

(註:結局Jcode::CP932はCPANにアップしました。)

 Jcode.pmにちょっとしたpatchをあてるだけで、Jcode::CP932はこんなにすっきりしてしまいましたよ。

package Jcode::CP932;
require 5.008001;
our $VERSION = '0.05';

use warnings;
use strict;

use Jcode ();

our @ISA         = qw(Jcode);
our @EXPORT      = qw(jcode getcode);
our @EXPORT_OK   = qw($VERSION $DEBUG);
our %EXPORT_TAGS = ( all       => [ @EXPORT, @EXPORT_OK ] );

our $DEBUG;
our $FALLBACK;
*DEBUG    = \$Jcode::DEBUG;
*FALLBACK = \$Jcode::FALLBACK;

use overload 
    q("") => sub { $_[0]->euc },
    q(==) => sub { overload::StrVal($_[0]) eq overload::StrVal($_[1]) },
    q(.=) => sub { $_[0]->append( $_[1] ) },
    fallback => 1,
    ;

my $pkg = __PACKAGE__;

sub jcode {
    return $pkg->new(@_)
}

*getcode      = \&Jcode::getcode;

foreach my $func (qw/convert set append/) {
    no strict 'refs';
    *{"$pkg\::$func"} = \&{"Jcode::$func"};
}

use Encode::EUCJPMS;
$pkg->set_jname2e(
    sjis        => 'cp932',
    euc         => 'cp51932',
    jis         => 'cp50221',
    iso_2022_jp => 'cp50220',
    ucs2        => 'UTF-16BE',
);

1; # End of Jcode::CP932
__END__

 んで、Jcode.pmにあてるpatch(というか追加するメソッド)はこんな感じ:

sub set_jname2e {
    my $class = shift;
    my %new_jname2e = @_;
    foreach my $enc (keys %new_jname2e) {
        my $name = $new_jname2e{$enc} || $enc;
        my $e = find_encoding($name) or croak "$enc not supported";

        $jname2e{$enc}  = $name;
        $ename2j{$name} = $enc;
        no strict 'refs';
        no warnings 'redefine';
        *{"$class\::$enc"} = sub {
            my $r_str = $_[0]->{r_str};
            Encode::is_utf8($$r_str) ?
                $e->encode($$r_str, $_[0]->{fallback}) : $$r_str;
        };
    }
}

 要するにsjiseucへ変換するメソッドを書き換えるメソッド、ですね。

 もっといい方法があるのかもしれませんが、とりあえず。

 いかがでしょうか?>弾さん

 ちなみに上記のJcode::CP932-0.05は0.04と違い、Jcodeの動作にも影響を与えてしまいます(たぶん)。これは%jname2eと%ename2jを変更するため、convert,set,appendに影響を与えるためです*1

 したがってJcode::CP932なんてわざわざ作らなくても、Jcode.pmにset_jname2eメソッドを追加して、

use Encode::EUCJPMS;
Jcode->set_jname2e(
    sjis        => 'cp932',
    euc         => 'cp51932',
    jis         => 'cp50221',
    iso_2022_jp => 'cp50220',
    ucs2        => 'UTF-16BE',
);

――とかすればいいんじゃね? って話もあります*2

 うーん。Jcode::CP932を作るんであれば正規化処理を追加するのがいいかな。。。

 少なくともJcodeまわりのどこかで正規化処理を用意するのがよさそうだと思うんだけれど。

*1:逆に、ここに手を出せないために0.04ではいろいろ変なことをしてる。

*2:ただしこの場合は上記を正しく設定する必要があるので、あまり親切ではない気もします。