下記のプログラムをutf8で書いてみます。
use strict; use warnings; my $str = 'テスト'; print length $str, "\n"; # 9
実行すると「9」が出力されます。length関数は「テスト」をバイトとして扱うので、
返す結果は「3文字」ではなく「9バイト」になるわけです。
次にutf8プラグマを使うとどうなるか。
use strict; use warnings; use utf8; my $str = 'テスト'; print length $str, "\n"; # 3
実行すると「3」が出力されます。
utf8プラグマを使用すると日本語は1文字として扱われるようになるのです。
内部での扱いどうなっているのかというと、utf8かどうかを表すフラグが文字列に付与されています。
このフラグがついているかどうかで、length関数のように扱いが違ってきます。
utf8プラグマは、自動でこのフラグを文字列に付与します。
もし明示的に付与したり、外したりする時は、「utf8::decode」と「utf8::encode」を使用します。
# フラグを付与する utf8::decode($str); # フラグを外す # 何回もencodeするとおかしくなるので、フラグが付与されているかどうか調べる if (utf8::is_utf8($str) { utf8::encode($str); }
utf8プラグマは、文字列に自動的にフラグを付与するのですが、
これはプログラムに記述されている文字列だけです。
ファイルから読み込んだ文字列やデータベースから取ってきた文字列などは、utf8プラグマの効果が及んでいません。
これらなどには別の処理が必要になります。
ファイル読み込みは下記のように記述すれば良いです。
my $fh; open $fh, "<:utf8", './example.txt';
データベースに関しては、DBIでのオプション指定でできるみたいです。
MySQLの場合は、下記のようにすれば良いです。
my $dbh = DBI->connect(@args); $dbh->{mysql_enable_utf8} = 1;
ということで、前回の文字化けには、これで対処できるようになりました。