Encode::decode_utf8()であってもis_utf8()を使うべき理由
404 Blog Not Found:#perl - utf8::decode()ではなくEncode::decode_utf8()を使うべき理由
Validationの観点だけではなく、簡潔性の観点からも、Encode::decode_utf8()はおすすめです。すでに UTF-8 flag がついた文字列はそのままコピーするだけなので、条件分岐も不要です。
これは厳密にはこうなる。
Validationの観点だけではなく、簡潔性の観点からも、Encode::decode_utf8()はおすすめです。すでに UTF-8 flag がついた文字列はEncode-2.13以降であればそのままコピーするだけなので、条件分岐も不要です。
Encode-2.12ではそのままコピーしてない。そのままコピーするのは2.13以降での実装。
--- Encode-2.12/Encode.pm 2005-09-08 23:17:34.000000000 +0900 +++ Encode-2.13/Encode.pm 2006-01-16 00:06:45.000000000 +0900 @@ -200,6 +199,7 @@ sub decode_utf8($;$) { my ($str, $check) = @_; + return $str if is_utf8($str); if ($check){ return decode("utf8", $str, $check); }else{
よって、Encode-2.12環境だと、
#!/usr/bin/perl use strict; use warnings; use Encode; use Devel::Peek; { use utf8; my $bytes = '松鵜'; Dump($bytes); my $utf8 = decode_utf8($bytes); Dump($utf8); }
これはエラーになる。
SV = PV(0x7120f0) at 0x72ba70 REFCNT = 1 FLAGS = (PADBUSY,PADMY,POK,pPOK,UTF8) PV = 0x721460 "\346\235\276\351\265\234"\0 [UTF8 "\x{677e}\x{9d5c}"] CUR = 6 LEN = 8 Cannot decode string with wide characters at /usr/lib64/perl5/5.8.8/x86_64-linux/Encode.pm line 166.
よって、例えばこうするのが無難。
#!/usr/bin/perl use strict; use warnings; use Encode; use Devel::Peek; { use utf8; my $bytes = '松鵜'; Dump($bytes); my $utf8 = Encode::is_utf8($bytes) ? $bytes : decode_utf8($bytes); Dump($utf8); }
utf8:is_utf8()ではなくEncode::is_utf8()を使うのが多分スマート。
なんでまだEncode-2.12を使ってるんだ!
と怒られそうだが、開発の現場ではEncode-2.12を使ってる可能性が高い。理由は次のとおり。
だったらバージョンを上げればいいじゃない
いやいや、上げられない環境ってのもありまして。
- バージョンを上げる権限がない
- 勝手にPerlモジュールをインストールするとサポート対象外
- perlのRPMパッケージで提供されるEncodeとの整合性で云々*1
- pure perlなモジュールしかインストールできない*2
- でも性能劣化は避けたい
とかとか。あるよねー。え?ない?俺だけ?
各OSで提供されているPerlのバージョン
ついでなので、他のOSもざっと調べてみた。
OS名 | Perlのバージョン | 備考 |
---|---|---|
Debian stable(lenny) | 5.10.0 | oldstable(etch)は5.8.8 |
Fedora 11 | 5.10.0 | Fedora 8は5.8.8 |
Gentoo | 5.8.8 | stableもunstableも5.8.8 |
openSUSE stable(11.1) | 5.10.0 | 10.3は5.8.8 |
RHEL5 | 5.8.8 | CentOS5も同様 |
Ubuntu 9.04 | 5.10.0 | 8.04は5.8.8 |
Vine Linux 5 | 5.10.0 | Vine-4.2は5.8.6 |
FreeBSD 7.2 | 5.10.0 | 7.1は5.8.8 |
Mac OS X(Snow Leopard) | 5.10.0 | Leopardは5.8.8 |
RHEL5とGentoo以外は5.10.0だが、他もつい最近まで5.8.8だった。残念ながらEncode-2.12はまだまだ現役。
Gentooがいまだに5.8.8なのは、SpamAssassinなど5.10.0と組み合わせると行儀が悪いクソモジュールがあるためのようで。いやー大変ですなぁ。