Baldanders.info

リニューアル詳細 2

昨日の続き。

del.icio.us の daily blog posting 機能は悪くないのだが, うちの Movable Type では再構成時に上手くカテゴリ情報が入らない。 DB にはちゃんと入っていて, 手動で再構成するとちゃんとカテゴリ情報も入る。 なんだかなぁ。 この MT 3.3x シリーズは異様にバグが多い気がするんだけど大丈夫なんだろうか。 しょうがないので POST 時にカテゴリを指定するのを止めた。

昨日書いた RSS を JSONP に変換する CGI だが, 何が大変だったかというと, 日本語が文字化けしやがるのだ。 例えば「Vox にガチャピン登場!」というタイトルを CGI に通すと,

"Vox \x{306b}\x{30ac}\x{30c1}\x{30e3}\x{30d4}\x{30f3}\x{767b}\x{5834}\x{ff01}"

ってな感じの謎の16進コードになる。 よく見ると分かると思うが, これは UTF-16 (人によっては UCS-2 という人もいるが UCS は文字集合をさすものなので厳密には間違い)による文字エンコーディングを16進ダンプしたものである。 私は Perl はあまり詳しくないので, もう調べまくりましたよ。 CPAN のドキュメントとかも見たけど, そもそもマルチバイト文字をどう取り扱っているかという情報が全然ないのね。 それでようやく見つけたのがこの記事。

これによると

「UTF-8フラグがついていると、UTF8の文字列が正しく文字として認識されてlengthがバイト数よりも小さくなるのでエスケープするようになる」

などという恐ろしい事が書かれていた。 この記事では Data::Dumper::qquote() を無効にする対処をされていたが, この方法では文字列の引用符が外れてしまうという致命的な問題が起きる。 そこでちょっと考えて Dumper() の出力結果に対して

$json=~s/\\x\{([a-fA-F0-9]{4})\}/\%u$1/g;

ってな感じで置換操作を加えてやることにした(正規表現が野暮ったいのはご容赦)。 こうすれば上記の文字列は

"Vox %u306b%u30ac%u30c1%u30e3%u30d4%u30f3%u767b%u5834%uff01"

となり, JavaScript の unencode 関数でなんとかデコードできる。

しかしなんちうか, マルチバイト圏の人間から見れば文字数と文字列のバイト数が異なるのは当たり前の話で, しかもそのギャップを回避するのに(いくら Data::Dumper だからって)文字コードをダンプ表示するなどというあり得ない解決法を平気でやらかす感覚はどうにも理解しがたい。 これが Perl 文化なのか? こんなことに手間を取らせないで欲しい。

CGI の仕様についてはドキュメントをそろえてから公開する予定。