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

时间:2009-11-25 13:28:36

标签: perl unicode utf-8 migration legacy

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

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

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

2 个答案:

答案 0 :(得分:11)

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

如果您需要处理文件中的UTF-8数据,或者将UTF-8写入文件,则需要在文件句柄上设置编码,并将数据编码为外部位数。例如,请参阅With a utf8-encoded Perl script, can it open a filename encoded as GB2312?

查看告诉您Unicode的Perl文档:

另见Juerd's Perl Unicode Advice

答案 1 :(得分:4)

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

  • 尽管perl doc建议“只在必要时”,请继续使用'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)无效!
  • 记得转换你的输入 - 例如。在Web应用程序中,传入的表单数据可能需要解码
  • 确保所有开发人员都知道编码/解码这个术语的方式 - perl中的'utf8字符串'是/ de / -coded形式,包含utf8数据的原始字节字符串是/ en / -coded
  • 正确处理您的URL - / en / -code将utf8字符串转换为字节,然后执行%xx编码以生成URL的ASCII形式,并在从mod_perl读取时对其进行/ de / -code(例如。{ {1}})
  • 对于网络应用程序,请记住HTTP标头中的字符集会覆盖使用$uri=utf_decode($r->uri())指定的字符集
  • 我确信这个不言而喻 - 如果你做任何字节操作(例如,数据包数据,按位操作,甚至是MIME内容长度标题),请确保使用字节而不是字符计算
  • 确保您的开发人员知道如何确保他们的文本编辑器设置为UTF-8,即使给定文件上没有BOM
  • 请记住确保您的修订控制系统(对于google的好处 - subversion / svn)将正确处理文件
  • 在可能的情况下,坚持使用ASCII来获取文件名和变量名 - 这可以避免在移动代码或使用不同的开发工具时出现可移植性问题

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

我相信你已经把这些中的大部分都整理好了,但希望所有能帮助那些人的人避免我们经历的许多小时调试。