我想知道为什么大多数使用Perl构建的现代解决方案在默认情况下不启用UTF-8。

我知道核心Perl脚本有许多遗留问题,可能会破坏一些东西。但是,从我的角度来看,在21世纪,大型的新项目(或具有大视角的项目)应该从头开始使他们的软件支持UTF-8。但我还是不认为会发生这种情况。例如,Moose启用严格和警告,但不启用Unicode。现代的::Perl也减少了样板文件,但没有UTF-8处理。

为什么?在2011年的现代Perl项目中,是否有一些避免使用UTF-8的理由?


评论@tchrist太长了,所以我把它加在这里。

看来我没有说清楚。让我试着补充一些东西。

我和他对情况的看法很相似,但我们的结论却完全相反。我同意,Unicode的情况是复杂的,但这就是为什么我们(Perl用户和编码员)需要一些层(或pragma),使UTF-8的处理像现在一样简单。

它指出了许多方面,我将阅读和思考他们几天甚至几个星期。不过,这不是我的重点。tchrist试图证明“启用UTF-8”不是一种单一的方法。我没有那么多的知识与之争论。所以,我坚持用活生生的例子。

我玩了Rakudo和UTF-8只是我需要的。我没有遇到任何问题,一切都很顺利。也许有一些更深层次的限制,但在开始时,我所测试的所有工作都符合我的预期。

这难道不应该是现代Perl 5的目标吗?我要强调的是:我并不是建议将UTF-8作为核心Perl的默认字符集,而是建议开发新项目的人员可以使用snap触发它。

Another example, but with a more negative tone. Frameworks should make development easier. Some years ago, I tried web frameworks, but just threw them away because "enabling UTF-8" was so obscure. I did not find how and where to hook Unicode support. It was so time-consuming that I found it easier to go the old way. Now I saw here there was a bounty to deal with the same problem with Mason 2: How to make Mason2 UTF-8 clean?. So, it is pretty new framework, but using it with UTF-8 needs deep knowledge of its internals. It is like a big red sign: STOP, don't use me!

我真的很喜欢Perl。但是处理Unicode是痛苦的。我仍然发现自己在撞墙。在某种程度上tchrist是正确的,并回答了我的问题:新项目不吸引UTF-8,因为它在Perl 5中太复杂了。


当前回答

在阅读这篇文章时,我经常有这样的印象,人们使用“UTF-8”作为“Unicode”的同义词。请区分Unicode的“码点”,即ASCII码的放大版,以及Unicode的各种“编码”。有一些,其中UTF-8, UTF-16和UTF-32是目前使用的,还有一些已经过时了。

请注意,UTF-8(以及所有其他编码)仅在输入或输出中存在并具有意义。在内部,从Perl 5.8.1开始,所有字符串都保留为Unicode“代码点”。的确,您必须启用前面提到的一些特性。

其他回答

在野外有大量的古老代码,其中大部分以公共CPAN模块的形式存在。我发现,如果我使用可能受Unicode影响的外部模块,我必须非常小心地启用Unicode,并且仍然试图在我经常使用的几个Perl脚本中识别和修复一些与Unicode相关的故障(特别是,由于转码问题,iTiVo在任何不是7位ASCII的东西上都严重失败)。

在阅读这篇文章时,我经常有这样的印象,人们使用“UTF-8”作为“Unicode”的同义词。请区分Unicode的“码点”,即ASCII码的放大版,以及Unicode的各种“编码”。有一些,其中UTF-8, UTF-16和UTF-32是目前使用的,还有一些已经过时了。

请注意,UTF-8(以及所有其他编码)仅在输入或输出中存在并具有意义。在内部,从Perl 5.8.1开始,所有字符串都保留为Unicode“代码点”。的确,您必须启用前面提到的一些特性。

您应该启用unicode字符串特性,如果使用v5.14,这是默认值;

你真的不应该使用unicode标识符,特别是对于通过utf8的外部代码,因为它们在perl5中是不安全的,只有cperl可以做到这一点。参见http://perl11.org/blog/unicode-identifiers.html

关于文件句柄/流的utf8:您需要自行决定外部数据的编码。库不可能知道这一点,因为甚至libc也不支持utf8,所以正确的utf8数据很少。有更多的wtf8,窗口畸变的utf8左右。

顺便说一句:Moose并不是真正的“现代Perl”,他们只是劫持了这个名字。Moose是完美的Larry wall风格的后现代perl,混合了Bjarne stroustrup风格的一切,有一个折衷的perl6语法,例如使用字符串作为变量名,可怕的字段语法,以及一个非常不成熟的幼稚的实现,比正确的实现慢10倍。 Cperl和perl6是真正的现代perl,其中形式服从功能,实现得到了简化和优化。

我认为您误解了Unicode及其与Perl的关系。无论您以何种方式存储数据,Unicode、ISO-8859-1或许多其他东西,您的程序都必须知道如何将获得的字节解释为输入(解码),以及如何表示想要输出的信息(编码)。如果解释错误,数据就会失真。在你的程序内部没有什么神奇的默认设置来告诉程序外部的东西如何操作。

You think it's hard, most likely, because you are used to everything being ASCII. Everything you should have been thinking about was simply ignored by the programming language and all of the things it had to interact with. If everything used nothing but UTF-8 and you had no choice, then UTF-8 would be just as easy. But not everything does use UTF-8. For instance, you don't want your input handle to think that it's getting UTF-8 octets unless it actually is, and you don't want your output handles to be UTF-8 if the thing reading from them can't handle UTF-8. Perl has no way to know those things. That's why you are the programmer.

我不认为Perl 5中的Unicode太复杂。我认为这很可怕,人们会避免这样做。这是不同的。为此,我在第6版《学习Perl》中加入了Unicode,在《有效Perl编程》中也有很多关于Unicode的东西。您必须花时间学习和理解Unicode及其工作原理。否则你将无法有效地使用它。

我们都同意这是一个困难的问题,原因有很多, 但这正是我们努力让每个人都更轻松的原因。

CPAN上最近有一个模块utf8::all,它试图“打开Unicode”。所有的一切”。

正如已经指出的那样,您不能神奇地让整个系统(外部程序、外部web请求等)也使用Unicode,但是我们可以一起工作,创建合理的工具,使解决常见问题变得更容易。这就是我们成为程序员的原因。

如果utf8::all没有做一些您认为它应该做的事情,让我们改进它使其更好。或者让我们制作额外的工具,尽可能地满足人们不同的需求。

`