open:utf8 pragma如何在perl中工作 - 与CPAN模块有关?

时间:2013-07-01 15:39:30

标签: perl

我已经阅读了下一篇文章:

但可能错过了一些基本要点。

使用

use open(:utf8);

也会影响cpan模块?例如。当某个CPAN模块打开任何文件时,它将以:utf8打开?这个陈述是真的吗? (或者open pragma只是词法范围?)AFAIK - 它也影响模块,但是以“不一致”的方式...(可能是模块的问题)。

open pragma产生opendir效果? - 我已经尝试过 - 没有 - 我仍然需要decode所有文件名的额外readdir(除了NFC)。那么,IO :: Dir是不同的东西 - open pragma没有涵盖什么?

影响open pragma sockets,管道呢? (例如什么是IO :: Handle?)

所有(或大多数)CPAN模块都知道何时进行i / o他们需要做什么(utf8或lattin1或raw?)(可能不是,因为简单的autodie不适用于{{ 1}} pragma ... :()

在很多地方我都可以阅读类似的规则:记住Unicode的规范规则:始终在应用程序的边缘编码/解码。这是一个很好的规则 - 但应用程序边缘意味着:我的自己的源代码。 CPAN模块(通常)位于边缘之后 - 不仅仅是“外部世界”,如系统或网络......

根据我的经验,我的短脚本(大量使用CPAN)中的3/4内容包含:顶级声明,以及几乎所有内容的数十种编码/解码/ NFC ......

例如为: 即使是日志记录实用程序,也需要显式编码:

open

即使想要在我的代码中添加use Log::Any qw($log); use Log::Any::Adapter ('File', 'file.log'); $log->error( encode('utf-8', "tökös")); ,也需要将每个tie $key替换为编码版本。

这是真的,还是我错过了上述doccu中的一些基本观点?

一些处理utf8(内部)的CPAN模块,如JSON :: XS,YAML :: XS,File :: Slurp ..(从未成功从YAML :: XS中获取正确的“东西”,纯YAML和JSON :: XS没有任何问题......

对于某些模块存在“hacks” - 如$valueDBIx::Class::ForceUTF8Template::Stash::ForceUTF8 - 等等, - 什么不允许为“both”和“非”写入正确的应用程序utf world ...;(

许多CPAN模块不会在内部调用上面的“黑客变种” - (例如HTML::FillInForm::ForceUTF8)但只是简单的一个,所以用utf8无法正确使用它们......其他人,默默地失败..;(

Plack应用程序不处理utf8 日志消息而没有烦人的“宽字符......”;(/现代perl :(并且可以继续;(

从上面我“扣除”(可能是错误的) - 比我必须知道并记住每个CPAN模块如何处理utf8编码的字符串,因为没有一些“注册表” - 是主要是基于试验/错误。

所以主要问题是:

虽然我记得:这里没有灵丹妙药但是这里有一些好方法如何检测并且知道“ utf8 ready CPAN模块“在使用它们之前不需要特殊的编码/解码?

如果有人需要知道,我正在使用我的每个脚本中的下一个:

HTML::FillInForm::ForceUTF8

嗯..刚刚“发现”了use 5.014; use warnings; use utf8; use feature qw(unicode_strings); use charnames qw(:full); use open(:utf8); #this sometimes is bad, so using only open qw(:std :utf8); use Encode qw(encode decode); use Unicode::Normalize qw(NFD NFC); perl模块用解码版本替换utf8:all的内容。

1 个答案:

答案 0 :(得分:5)

Empahsis mine:

  

open pragma作为声明所有I / O的默认“层”(也称为“学科”)的接口之一。在此pragma的词法范围中找到的任何双参数openreadpipe(又名qx//)和类似运算符将使用声明的默认值。当这个编译指示在open中没有指定IO层时,即使是三个参数MODE也可能会受到影响。

所以不,它不会影响任何不存在pragma的代码。如果传递给pragma范围之外的代码,在这样的pragma范围内打开的句柄不会丢失它的层。


测试模块所需的内容:

输入

  • 测试1
    • 让输入源返回一个字符串,其中包含80..FF的代码点,并且FF上方没有代码点。
  • 测试2
    • 让输入源返回一个包含高于FF的代码点的字符串。

输出

  • 测试1
    • 输出一个字符串,其中包含80..FF的代码点,FF上没有代码点。首先将字符串传递给utf8::downgrade($_);
  • 测试2
    • 与测试1相同,但首先将字符串传递给utf8::uprade($_);
  • 测试3
    • 输出包含高于FF
    • 的代码点的字符串