September 30, 2005

use encoding 'utf-8' & encoding::warnings

Perl ネタ。

XML まわりなんかを扱うときについて回る UTF-8 フラグ (Unicode フラグ)をどう落とすか的ネタがもりあがっていますねぇ。このネタは拙書の Blog Hacks でも 1 Hack さいて解説してあります。

Blog Hacks ―プロが教えるテクニック&ツール100選
宮川 達彦 伊藤 直也
オライリー・ジャパン (2004/08/07)
売り上げランキング: 20,714

たしかに内部的に UTF-8 フラグを落としてバリバリつなげちゃえば、場当たり的に楽は楽なんだけど、内部的に Unicode フラグをもったまま処理して、最後に出力するときに落とす(encode する)というのが正当なわけです。

また、Unicode flagged + non-Unicode flagged な処理を行ったときに warning もしくは例外をとばすプラグマ encoding::warnings なんてのもありますし(実験的なのでプロダクション環境ではオススメしない)、このドキュメントには、問題の概要と対処法がちゃんと載ってます。

Upgrade both sides to unicode-strings If your program does not need compatibility for Perl 5.6 and earlier, the recommended approach is to apply appropriate IO disciplines, so all data in your program become unicode-strings. See encoding, open and "binmode" in perlfunc for how.

Perl 5.6 以下での互換性が必要ないなら、すべてを Unicode String として扱い、読み書きするときには encoding 指定したり binmode を利用する。

Downgrade both sides to byte-strings The other way works too, especially if you are sure that all your data are under the same encoding, or if compatibility with older versions of Perl is desired.

すべてを byte 列で扱う。すべてのデータが同じエンコーディング(たとえば utf-8) であることを保証でき、また過去の Perl バージョンとの互換性がほしいならこれもよい。

Specify the encoding for implicit byte-string upgrading If you are confident that all byte-strings will be in a specific encoding like UTF-8, and need not support older versions of Perl, use the encoding pragma:

implicit なアップグレード(デフォルトは latin-1 => utf-8)に利用するエンコーディングを use encoding プラグマで指定する。use encoding 'utf-8' とすると、flag つきと flag なしを結合したときの implicit なアップグレードが発生しない。

というわけで、コードをいじらずにサクっと対処するには use encoding "utf-8" がかなり有効だとおもわれます。これでは利かないおおきなアプリケーションでは、内部的に Unicode フラグをつけて扱うといった処理が Best Practice でしょう。

問題は CPAN モジュール(とくに XS系)で、内部で勝手にフラグを落としてしまったり、フラグつきだと Segfault するようなモノがいくつか存在するところですね。Wiki ページでもつくってこの情報をアップデートできるとよいんですが。

Posted by miyagawa at September 30, 2005 04:02 PM | Permalink | Comments (0) | TrackBack(0)
Comments
Trackbacks
TrackBack URL for this entry: http://blog.bulknews.net/mt3/mt-tb.cgi/1819
Post a comment