PerlのEncodeについて

とある事情でCGIをひさびさに書くことになった。
置くのがレンタルサーバということもあり、言語はPerlを選んだ。

ここで文字コードを変換する必要があり、その際にEncodeの使い方を日本語のWebPageの範囲で調べてみたがピンとこない。
そこで、CPANの小飼氏の文章を読むと、ストンと腑に落ちた。
http://search.cpan.org/dist/Encode/Encode.pm


乱暴にではあるが、まとめることでメモ(備忘録)とする。

Perlにとっては原則データは単なるバイトの並びとして扱ってきた。これは文字列とて同様である。(もともとPerlアメリカ人によって開発されたため、ASCIIが扱えればそれで充分だったのだ。)
しかし、このままではマルチバイト文字列を扱えないため、5.6以降のPerlでは以下の策をとることにした。

文字列中に1バイトよりも大きな文字コードを含む文字を文字列中に含むとき、必ずUTF8で文字コード格納する。
ただ、これだとバイト列と見分けがつかないため、'UTF8フラグ'をONにすることでバイトストリームと文字列を区別して扱えるようにする。


つまり、Perlにとって「UTF8の文字コードが連続したデータ列でかつUTF8フラグがONになっている」のがPerlの内部文字列データと呼ぶことができる。

Encode()は「他の文字列コードにデータを変換する」という捉え方でなく、Perlの内部文字列データから、単なるバイトストリームへの変換」という視点で捉える必要がある。

$octets = encode("shiftjis", $string);

というのは、Perlの内部文字列から「文字コードUTF-8からシフトJISに変換しUTF8フラグをOFFした値」に変換することである。
いくらシフトJIS文字コードが連続していて、文字として意味があっても、変換後の値$octetsは単なるバイト列にすぎない。

decodeはその逆で「あるバイト列を第一引数で指定した文字コードで構成されていると見なし、その値をUTF-8文字コードでかつUTF8フラグをONにした内部文字列データ」に変換する。

では、from_to()は?
from_to()とは文字コードを変換するだけのI/Fであり、UTF8フラグを操作しない
したがって、たとえUTF8に変換しても、そのままではPerlにとって単なるバイト列にすぎない。
この点注意が必要である。