■2004-10-03
* [今月のAcme] Acme::BadExample
ばたばたして結局9月分ですが。Acme::BadExample。悪いお手本。文法的には妥当なのに、コードとしては滅茶苦茶というモジュールです。動きません。動かせたら作者が100ドルくれるそうです。で、これのドキュメントにも登場するPPIというモジュールは、PurePerlなPerlパーサ(Parse::Perl::Isolated)で非常に興味深いものです。そのうち訳してみたいなあ。そのPPIは正しく解析できるけれども、現実には動かない……だからBadExampleということだそうで。このモジュールはコードの面白さが肝なので、別ページにて紹介です。
* [Perl] EncodeとMIME-Header
Re: 全角半角変換という記事(この紹介からEncode+mod_perlとphpの比較経由)で、"utf8 -> MIME-Header への Encode では、行末の折り返しが一般化できないため、現時点では=?UTF-8?= 決め打ちになっています"
とあります。どうやらJEncodeに加えたISO-2022-JPエンコード用クラスの処理は何か間違っているらしいのですが、何が問題なのかわかりません。う〜ん、どうしよう…… (ちなみにJcodeのChangesによると、日本語変換に関して現在のJcodeはEncodeよりも高速)。
その問題はひとまず置いておいて、JEncodeの機能追加。渡された文字列のUTF8フラグをチェックするようにしました。CPANモジュールの中にはPerl5.8以降で使用するとutf8エンコーディングされた文字にUTF8フラグを勝手に立ててしまうものがあるので、その対応です。use utf8
したコード内部でも正しく動作するはずです。ただしその場合は$JEncode::UTF8を真にします。$j->utf8
で返される値にUTF8フラグを立て整合性をとります。また、print "$j"
とやったときにもeuc-jpではなくUTF8フラグ付きのutf8エンコーディングされた文字列が出力されます。
[追記]
ああ、そうか。Encode::MIME::Headerの実装は、utf8を1キャラクタずつ取り出してbytes::lengthでバイト数を計算し、75バイトを超えると折り返すようになっているのですが、これだとiso-2022-jpのバイト数を計算できないですね。iso-2022-jpを1バイト毎に取り出せば正しく折り返せますが、折り返しの部分でESCが切られちゃうとメーラによってはうまくdecodeできません。かといって単純にlengthを計算する前にiso-2022-jpに変換すると、非asciiが1文字ごとにESCで挟まれてしまい、エンコードされた文字列がとんでもなく長くなっちゃうし。
Danさんの書かれているとおり、正しく綺麗に処理させるのは結構面倒なので、現状JEncodeの実装である「mime-encodeする直前にiso-2022-jpに変換」のままにしておきます。"ア1イ2ウ3エ4オ5カ6キ7ク8ケ9コ0"みたいなエスケープシーケンスに挟まれまくりのサブジェクトでない限りは、utf8で計算されたバイト数を超えることもないでしょう。
[追記] JEncode v.1.33で解決しました。(2004-11-04)