将旧版Perl代码移至UTF-8时,我应该注意哪些问题?

Nik*_*nko 7 migration legacy unicode perl utf-8

到目前为止,我工作的项目只在源代码中使用ASCII.由于I18N领域即将发生的一些变化,以及我们在测试中需要一些Unicode字符串,我们正在考虑咬住子弹并将源代码移动到UTF-8,同时使用utf8pragma(use utf8;)

由于代码现在是ASCII,我不希望代码本身有任何问题.但是,我不太清楚我们可能会遇到任何副作用,而我认为考虑到我们的环境(perl5.8.8,Apache2,mod_perl,带FreeTDS驱动程序的MSSQL服务器),我很可能会得到一些副作用.

如果你过去做过这样的迁移:我可以期待什么问题?我该如何管理它们?

bri*_*foy 11

utf8pragma仅告诉Perl您的源代码是UTF-8编码的.如果你在源代码中只使用了ASCII,那么Perl理解源代码就不会有任何问题.您可能希望在源代码管理中创建一个分支以确保安全.:)

如果您需要处理文件中的UTF-8数据,或者将UTF-8写入文件,则需要在文件句柄上设置编码,并将数据编码为外部位预期的数据.例如,请参阅使用utf8编码的Perl脚本,它是否可以打开编码为GB2312的文件名?.

查看告诉您Unicode的Perl文档:

另请参阅Juerd的Perl Unicode建议.


小智 4

几年前,我将我们内部的 mod_perl 平台 (~35k LOC) 迁移到 UTF-8。以下是我们必须考虑/改变的事情:

  • 尽管 Perl 文档建议“仅在必要时”,但仍应使用“use utf8;” 在每个源文件中 - 它为您提供一致性。
  • 将数据库转换为 UTF-8 并确保数据库配置将连接字符集设置为 UTF-8(在 MySQL 中,执行此操作时请注意 VARCHAR 的字段长度问题)
  • 使用最新版本的 DBI - 旧版本未在返回的标量上正确设置 utf8 标志
  • 使用 Encode 模块,避免使用 Perl 内置的 utf8 函数,除非你确切知道你正在处理什么数据
  • 读取UTF-8文件时,指定层 -open($fh,"<:utf8",$filename)
  • 在 RedHat 风格的操作系统(甚至 2008 年版本)上,包含的库不喜欢读取存储在 utf8 标量中的 XML 文件 - 升级 perl 或仅使用该:raw
  • 在较旧的 perls(甚至 5.8.x 版本)中,一些较旧的字符串函数可能是不可预测的 - 例如。$b=substr(lc($utf8string),0,2048)随机失败但$a=lc($utf8string);$b=substr($a,0,2048)有效!
  • 记得转换您的输入 - 例如。在网络应用程序中,传入的表单数据可能需要解码
  • 确保所有开发人员都知道编码/解码术语的含义 - Perl 中的“utf8 字符串”采用 /de/ 编码形式,包含 utf8 数据的原始字节字符串采用 /en/ 编码
  • 正确处理您的 URL - /en/-将 utf8 字符串编码为字节,然后进行 %xx 编码以生成 URL 的 ASCII 形式,并在从 mod_perl 读取时 /de/-编码(例如$uri=utf_decode($r->uri())
  • 对于 Web 应用程序来说,请记住 HTTP 标头中的字符集会覆盖使用指定的字符集<meta>
  • 我确信这一点不言而喻 - 如果您执行任何字节操作(例如数据包数据、按位操作,甚至 MIME 内容长度标头),请确保您使用字节而不是字符进行计算
  • 确保您的开发人员知道如何确保他们的文本编辑器设置为 UTF-8,即使给定文件上没有 BOM
  • 记住确保您的版本控制系统(为了谷歌的利益 - subversion/svn)将正确处理文件
  • 在可能的情况下,坚持使用 ASCII 作为文件名和变量名 - 这可以避免在移动代码或使用不同的开发工具时出现可移植性问题

还有一点——这是黄金法则——不要只是破解直到它起作用,确保你完全理解给定的编码/解码情况下发生了什么!

我确信您已经解决了大部分问题,但希望所有这些都可以帮助人们避免我们经历的长时间调试。