程序人生

写优雅的程序,做优雅的人

升级 Ruby 1.8.7 到 1.9.3

| Comments

这几天对一个大型的 Rails 项目做 Ruby 升级,把升级过程中遇到的几个主要问题和解决方法记录下来以备参考。

1. 带中文字符的源代码需要加上 utf-8 encoding 声明

在 Ruby 1.9 中,如果源代码中包含中文字符,必须声明源代码文件的字符集,具体做法是在文件头部增加一个注释行: # encoding: utf-8

做法很简单,但是当文件量很大时,一个一个手工修改文件也很麻烦,好在有一个 gem – magic_encoding 可以轻易解决这个烦恼。用法相当简单,通过 gem install magic_encoding 安装 gem,然后在 Rails 项目目录下执行 magic_encoding 命令,它自动把 Rails 项目所有源代码文件头部加上 # -*- encoding : utf-8 -*-,非常简单方便。

参考:magic_encoding in github

2. 改变 case var when value : 用法

在 Ruby 1.9 中,象下面这种 case when 语法已经不支持

1
2
3
4
5
6
7
8
  case var
    when 1:
      "value of 1"
    when 2,3:
      "value of 2 and 3"
    else
      "others"
  end

修改很简单,把 when value 后的冒号去掉就行了。

3. 字符串字符集问题

在 Ruby 1.9 中,字符串对象带有字符集属性,不同字符集的字符串之间拼接会报异常,通常我们都是用 utf-8 encoding 的字符串,但有些类库返回的字符串返回的字符串并非 utf-8 encoding,这时候可能导致问题,需要做一些额外处理。

例如,Base64 解码后的字符串并不是 utf-8 的,拼接会报异常,需要做一次 force_encoding,看下面的代码。

1
2
3
4
5
6
7
8
9
require 'base64'
s1 = "薄荷网"
puts s1.encoding.to_s
s2 = Base64.encode64(s1)
s3 = Base64.decode64(s2)
puts s3.encoding.to_s
s4 = s3.force_encoding('utf-8')
puts s4.encoding.to_s
puts "#{s3}很棒"

结果是

1
2
3
4
5
UTF-8
ASCII-8BIT
UTF-8
Encoding::CompatibilityError: incompatible character encodings: ASCII-8BIT and UTF-8
  blabla ...

所以在 Base64 处理字符串的地方要相当小心。

4. YAML 引擎改变引起的问题

Ruby 1.9.3 中,YAML 引擎 由 Syck 改成了 Psych,Psych 和 Syck 在处理 UTF-8 字符串时有明显的区别,详见 Psych、Syck、YAML 和编码

总结:把 Ruby 从 1.8 升级到 1.9 还是比较轻松的,遇到的问题比想象中少,而且解决起来都不算麻烦。Ruby 兼容性方法做得很棒,赞一个。

Comments