论坛首页 编程语言技术论坛

升级到Ruby 1.9 笔记二

浏览 3179 次
精华帖 (0) :: 良好帖 (2) :: 新手帖 (2) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-08-04  
Ruby 1.8 的字符串只支持ASCII码,在Ruby 1.9 增加了编码(Encoding)属性,能够支持Unicode. 新的功能有利于Ruby更好的支持国际化,但因为字符串对象被使用的太广泛,新的接口导致很多现有代码的修改。

+ 在Ruby1.8, string[index]会返回index所在位置的ACSII整数值:

irb(main):001:0> "123"[0]
=> 49


在Ruby1.9,string[index]会返回index所在位置的字符串:

irb(main):001:0> "123"[0]
=> "1"


如果你使用字符串保存二进制数据,还希望能够继续用索引来获得index所在位置的字节,可以采用以下方法:

irb(main):002:0> "123".getbyte(0)
=> 49


+ 在Ruby1.8,你可以直接对string[index]赋整数值:

irb(main):002:0> s = "123"
=> "123"
irb(main):005:0> s[1] = 53
=> 53
irb(main):006:0> s
=> "153"


在Ruby1.9, 会抛出异常:

irb(main):003:0> s = "123"
=> "123"
irb(main):004:0> s[1] = 53
TypeError: can't convert Fixnum into String
        from (irb):4:in `[]='
        from (irb):4
        from /usr/local/ruby-1.9.1/bin/irb:12:in `<main>'


可以用新的setbyte方法来赋值:

irb(main):005:0> s.setbyte(1, 53)
=> 53
irb(main):006:0> s
=> "153"


+ 在Ruby 1.8, "%d" % nil 会返回 “0”
在Ruby1.9, "%d" % nil 会导致TypeError异常

+ 如果在你的字符串中有特殊字符会导致无法用这个字符串来构建正则表达式:

irb(main):001:0> s = "\233901234560"
=> "\x9B901234560"
irb(main):003:0> s.encoding
=> #<Encoding:UTF-8>
irb(main):002:0> Regexp.new(s)
RegexpError: invalid multibyte character: /�901234560/
        from (irb):2:in `initialize'
        from (irb):2:in `new'
        from (irb):2
        from /bin/irb:12:in `<main>'


解决办法是采用二进制编码格式(ASCII-8BIT):

irb(main):008:0> new_str = s.force_encoding("ascii-8bit")
=> "\x9B901234560"
irb(main):009:0> Regexp.new(new_str)
=> /�901234560/
irb(main):010:0> 


+ 从MySQL数据库返回的字符串默认是ASCII-8BIT格式,但当你用这个字符串来格式化另一个字符串的时候,如果其中包含特殊字符,就会导致异常。下面手工初始化一个ASCII-8BIT的字符串:

irb(main):010:0> str = String.new
=> ""
irb(main):011:0> str << 233
=> "\xE9"
irb(main):012:0> str.encoding
=> #<Encoding:ASCII-8BIT>
irb(main):014:0> new_str = "%c%s" % [245, str]
Encoding::CompatibilityError: incompatible character encodings: UTF-8 and ASCII-8BIT
        from (irb):14:in `%'
        from (irb):14
        from /bin/irb:12:in `<main>'


解决办法是首先用String.new构建一个ASCII-8BIT格式的字符串,然后用<<和+运算符:

irb(main):015:0> new_str = String.new
=> ""
irb(main):016:0> new_str << 245
=> "\xF5"
irb(main):017:0> new_str += str
=> "\xF5\xE9"


   发表时间:2010-08-05  
好像变复杂了.......
0 请登录后投票
   发表时间:2010-08-07  
#让ruby1.8兼容1.9的写法

if RUBY_VERSION < '1.9'
  p 'do as ruby 1.9'
  #为字符串类添加force_encoding和ord方法
  class String
    unless defined?(String.new.bytesize)
      def bytesize
        self.size
      end
    end
    def force_encoding(s)
      self
    end
    def ord
      self[0]
    end
  end
  #为Hash类添加key方法

  class Hash
    def key(k)
      self.index(k)
    end
  end
  #为数字类添加ord方法
  class Fixnum
    def ord
      self
    end
  end
end

0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics