天真的Perl 6程序在Unicode方面不是往返安全的。它似乎在内部使用规范化表格组合(NFC)作为Str类型:
$ perl -CO -E 'say "e\x{301}"' | perl6 -ne '.say' | perl -CI -ne 'printf "U+%04x\n", ord for split //'
U+00e9
U+000a
通过文档我无法看到有关此行为的任何内容,我发现它非常令人震惊。我不敢相信你必须回到字节级别来往返文本:
$ perl -CO -E 'say "e\x{301}"' | perl6 -e 'while (my $byte = $*IN.read(1)) { $*OUT.write($byte) }' | perl -CI -ne 'printf "U+%04x\n", ord for split //'
U+0065
U+0301
U+000a
所有文本文件都必须在NFC中才能安全地使用Perl 6进行往返行程吗?如果该文件应该在NFD中怎么办?我必须在这里遗漏一些东西。我无法相信这是故意的行为。
答案 0 :(得分:6)
答案似乎是使用Uni类型(NFD,NFC等的基类),但它现在并没有真正做到这一点,并且没有好办法将文件转换为Uni字符串。因此,在将来某个未命名的点之前,除非将其视为字节,否则不能往返非规范化文件。
答案 1 :(得分:3)
使用UTF8-C8
。来自documentation:
您可以将UTF8-C8与任何文件句柄一起使用来读取确切的字节 他们在磁盘上。如果打印,打印时它们看起来很有趣 它使用UTF8手柄。如果你将它打印到手柄所在的位置 输出是UTF8-C8,然后它会像你通常期望的那样呈现, 并且是字节精确副本的字节。