utf8フラグがよくわかっていない件の回答

http://d.hatena.ne.jp/tori243/20100510/1273497722
不完全だけどこれの回答。

decodeした時に結果がころころ変わる件の原因

自分のコメント内容を再検証してみると…

1.フラグOFFした後。
 文字コード→utf8

とあるけど、そもそもこれが間違い!
「latin-1」でした。


Unicode::Japaneseで判定するとutf8が返ってきてしまうのだけど、
実際の中身はlatin-1になってた。
検証コード

my $str = encode("latin-1",$rs->{link}->{field});
say "dbg1:",Dumper($str);
utf8::decode($str);
say "dbg2:",Dumper($str);

結果

dbg1:$VAR1 = '全国一括';
dbg2:$VAR1 = "\x{5168}\x{56fd}\x{4e00}\x{62ec}";

なんでlatin-1?

Web::Scraperデバッグしてて気付いた。
http://cpansearch.perl.org/src/MIYAGAWA/Web-Scraper-0.24/lib/Web/Scraper.pm
(一部略)

    if (blessed($stuff) && $stuff->isa('URI')) {
        require Encode;
        require HTTP::Response::Encoding;
        my $ua  = $self->user_agent;
        my $res = $ua->get($stuff);
        if ($res->is_success) {
            my @encoding = (
                $res->encoding,
                # could be multiple because HTTP response and META might be different
                ($res->header('Content-Type') =~ /charset=([\w\-]+)/g),
                "latin-1",
            );
            my $encoding = first { defined $_ && Encode::find_encoding($_) } @encoding;
            $html = Encode::decode($encoding, $res->content);
        } else {
            croak "GET $stuff failed: ", $res->status_line;
        }
        $current = $stuff->as_string;
    } elsif (blessed($stuff) && $stuff->isa('HTML::Element')) {
        $tree = $stuff->clone;
    } elsif (ref($stuff) && ref($stuff) eq 'SCALAR') {
        $html = $$stuff;
    } else {
        $html = $stuff;
    }

ここの判定で「latin-1」になっていた。

というかそもそも

Web::Scraperのバージョンが古すぎなのが原因。
最新のだと直ってる*1

むー

自分が文字コードについて無知すぎる。
どこかで勉強しておかないと

*1:というか別環境だと再現しないから気付いた