GROUPエンジニアブログです。2010年05月2010年05月27日15:36カテゴリprogrammingあなたにも今日こそPerlの文字化けが理解できるたった一つの原則こんにちは。ECナビラボの須藤(@ajiyoshi)と申します。Perl(5.8以降)で文字化けに悩んだことはありませんか?私はあります。文字化け"などで検索すると、次のような単語が洪水のごとく溢れていて、なんだかよく分からなかったりしないでしょうか。いう方のために書かれています。今回こそは、ちゃんと理解してみませんか。文字化けしないために必要なことは、ほぼこの原則だた1点に集約されます。内部文字列とUTF8バイナリをきちんと区別する「ちょっと待って!」あなたは言います。Perlが内部的に保持している文字列の表現のこと。UTF8'と呼ばれる。UTF8'と呼ばれます。混同しやすいと私は思います。プログラマが知る必要はないのです。無用な混乱を避けるため、この文書では「内部文字列」と呼ぶことにします。Perlはいまやユニコードを知っており、内部文字列の文字境界を知っています。関数に内部文字列を渡すと、文字列に含まれる文字の数が返ります。現されるかを返します。「ECナビ」は4文字ですが、それをUTF8で表現すると8バイト必要になります。バイナリは比較できません。比較しても結果は偽です。部文字列とUTF8バイナリを結合しようとするのもよくないアイディアです。違うものなのだから当然ですね。データをナイーブに結合しようとするとどうなるでしょうか?普通は文字化けします。あなたが目にするPerlの文字化けの半分くらいはこれが原因です。内部文字列を作り出すではその内部文字列というのはどうすれば得られるのでしょうか。Encode::decodeを使います。CやJava風の型記法でシグネチャを表現すると次のようになります。bin);文字コードencでエンコーディングされたバイナリ配列binから、内部文字列を作り出すのがdecode()の役割です。length($strText);このコードをUTF8で保存して実行すれば、すでに述べたlengthの挙動を確かめることができます。内部文字列を特定のエンコーディングのバイナリ表現に変換する内部文字列というのはPerl内部でのお話です。テキストを書き出したり、DBに格納する必要があるでしょう。これにはEncode::encodeを使います。str);UTF8で書いたコードで、出力はEUC-JPで行う例を示します。ことが書いてあります。2点、おまけが1点あります。}おまけについては特に述べません。いうのを好む人もいれば、忌み嫌う人もいるでしょうから。使えばいちいちdecodeしなくても内部文字列を得られてだいぶ幸せになりました。xx.'これは、典型的には内部文字列をそのままprintに渡した場合に起きる警告です。まprintしたところでそれをコンソールとかDBとかブラウザとかの他の誰かが読むことができるなんてありえそうもないことです。Perlに教えてあげるべきです。');何も指定しなければ、readやprintや<STDIN>などはバイナリのまま読み書きしようとします。<$fh>は(内部文字列ではなく)バイナリ列を返すし、printには適切なエンコーディングで符号化されたバイナリ列を渡すべきです。strictなんてないし、Jcode.pmがどうとか書いてあります)が、Perlを新しくした瞬間に動かなくなってしまいそうです。ら自動的にEUC-JPに変換した上で書き出して欲しい」などとPerlに伝えることができます。close($fh);STDIN、STDOUTのようなすでに開いているファイルハンドルに同じことをするときは、binmode関数を使います。Perlの文字列について正しく理解しているのでない限り混乱の元だと私は思いますので、サンプルコードは割愛します。encode」の意味も理解できたのではないでしょうか。decodeしてやれば例えば冗長なUTF8符号化による微妙な脆弱性も防ぐことができます。utf8の隠れた副作用として、"あなたのチームのPerlの文字列についての理解度を試す"があると私は思います。utf8する」というのもひとつのポリシーではないかと思います。「妄撮」をやってみました。