Home > perl > latin-1 is not utf-8

latin-1 is not utf-8

  • 2009-01-31 (土) 18:31
  • perl
  • hatena count

use utf8 環境下で => オペレータの左辺が UTF8 flag on になってしまう – daily dayflower
ふむふむ。これは興味深い現象ですね。

まず初めにはっきりさせておくべきなのは、
latin-1の\x{a4} == U+00a4 == utf-8の\x{c2}\x{a4}
であるということですね。

use URI;

my $uri = URI->new('http://example.com/');

use utf8;

$uri->query_form( bytes => "\x{a4}" );
print $uri, "\n";
#=> http://example.com/?bytes=%C2%A4

で、それを踏まえると上記の結果の何が問題なのか分からないですよね。utf-8エンコーディングの正しい結果のような気がします。

結果をlatin-1で出したいのかutf8で出したいのかがはっきりしていないから期待する結果にならないのではないでしょうか。

utf8で出したいのであれば

use URI;

my $uri = URI->new('http://example.com/');

use utf8;
use Encode;

# utf8バイト列でエスケープしたい場合だけflagged utf8が許されると考えておk
$uri->query_form( bytes => decode('latin-1', "\x{a4}") );
# もしくはbyte列だけで行うほうが安全かな
# { use bytes;
#    $uri->query_form( bytes => "\xc2\xa4") );
# }
print $uri, "\n";
#=> http://example.com/?bytes=%C2%A4

と書くべきだろうし、latin-1で出したいのであれば
(すべてutf-8でプログラムコードを書いているという前提で)

use URI;

my $uri = URI->new('http://example.com/');

use utf8;
use Encode;

$uri->query_form( Encode::encode('latin-1', 'bytes') => "\x{a4}" );
print $uri, "\n";
#=> http://example.com/?bytes=%A4

と書くべきではないでしょうか。

思うに、このような出力するバイト列に操作を加えるメソッドにutf8 flaggedな文字列を渡すようにするには出力の文字コードも一緒に渡せるようになっていないと意味がないような気がします。なので、唯一安全なのは、あらかじめ出力する文字コードのバイト列に変換した値を渡すことではないでしょうか。むしろモジュール側がそう推奨すべきなのかな。

Comments:0

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://www.geminium.com/chiba_blog/2009/01/31/123/trackback/
Listed below are links to weblogs that reference
latin-1 is not utf-8 from へぼへぼCTO日記
add to hatena hatena.comment (5) add to del.icio.us (0) add to livedoor.clip (0) add to Yahoo!Bookmark (0) Total: 5

Home > perl > latin-1 is not utf-8

Search
Feeds
Meta

Return to page top