はまりました

  • 投稿日:
  • by
  • カテゴリ:

WWW::Mechanizeを利用して、ちょっとしたものを作成していたんですが、なぜが文字が化けてしまって、おかしいなぁ。この化け方って、どう考えても、utf-8に変換するときの問題だよな……。と思って探したら、WWW::Mechanize中に、こんなコードが……

# Try to decode the content. Undef will be returned if there's nothing to decompress.
# See docs in HTTP::Message for details. Do we need to expose the options there?
my $content = $res->decoded_content;
   $content = $res->content if (not defined $content);

decoded_contentは、HTTP::Messageにあって、

if ($ct && $ct =~ m,^text/,,) {
    my $charset = $opt{charset} || $ct_param{charset} || $opt{default_charset} || "ISO-8859-1";
    $charset = lc($charset);
    if ($charset ne "none") {
	require Encode;
	if (do{my $v = $Encode::VERSION; $v =~ s/_//g; $v} < 2.0901 &&
	    !$content_ref_iscopy)
	{
	    # LEAVE_SRC did not work before Encode-2.0901
	    my $copy = $$content_ref;
	    $content_ref = \$copy;
	    $content_ref_iscopy++;
	}
	$content_ref = \Encode::decode($charset, $$content_ref, Encode::FB_CROAK() | Encode::LEAVE_SRC());
    }
}

となっているので、Content-Typeが、text/....だったら、デフォルトはISO-8859-1としてEncode::decode、つまりUTF-8に変換しUTF-8フラグを立てることになるわけですな。そりゃ、文字化けもするよ……。

てか、オプションいるかい?じゃなくて、大至急何とかしろよ。と、思いつつも、ラッパークラスを作って対応。

そういえば、WWW::Mechanizeの1.22(現在のNetBSD pkgsrcの最新)より新しいバージョンはあるのかな?とcpanを探してみたら、最新の1.24では該当コードが削除されていて、開発版の1.29_01では

# Try to decode the content. Undef will be returned if there's nothing to decompress.
# See docs in HTTP::Message for details. Do we need to expose the options there? 
# use charset => 'none' because while we want LWP to handle Content-Encoding for 
# the auto-gzipping with Compress::Zlib we don't want it messing with charset
my $content = $res->decoded_content( charset => 'none' );
   $content = $res->content if (not defined $content);

と、なっていた。たしかに、そうよね……。さて、default_charsetをutf-8として指定するようにラッパークラスを書いてしまった私は、どうすればいいんだろう……。ま、得られた結果をutf-8としてencodeしてやればいいだけ……なの?かな?

あと、Class::DBI::Pagerを使っていて、1ページから最終ページまでじゃなくて、gooooogleみたいに、カレントページの周辺10ページにリンクを張るみたいなコトできないだろうか?と、調べてみたんだけど、よくわからない。

ただ、Changesに書いてある、Data::Page::Navigationってのが、それっぽくて、しかも、supportと書いてあるけれど、イマイチ使い方がよくわからないな。

Class::DBI::Pagerを継承する俺クラスでuse Data::Page::Navigationするってこと?なの?かな?でも、それって、supportなの?わからないね

なんにしても、プログラムを書くということは、たのしいものですな。それにしても、今さらながら、Class::DBIすげー。とか、ほんと、思う。