`
oliver_peng
  • 浏览: 44945 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

升级到Ruby 1.9 笔记二

    博客分类:
  • Ruby
阅读更多
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"


分享到:
评论
2 楼 sevk 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

1 楼 skyblue1984 2010-08-05  
好像变复杂了.......

相关推荐

    linux下redmine安装笔记

    需要注意的是,由于Redmine不支持Ruby 1.9版本,因此应遵循官方指南安装1.8版本。 3. **安装Subversion**: Redmine能够与版本控制系统集成,如Subversion。首先,通过`apt-get`安装Subversion。然后,使用`svn`...

    dj_mon:延迟作业的前端(不再维护)

    delayed_job_mongoid取决于mongoid 3.0这需要Ruby 1.9的,所以不存在用于支持ruby 1.8.7为。用法如果您使用的是Rails = &lt;3.1,或者config.assets.initialize_on_precompile设置为false,则将其添加到config/...

    java多线程笔试题-awesome-rubies:一组很棒的Ruby(编译器、解释器、虚拟机、解析器、文档生成器、版本管理器等)

    java多线程笔试题真棒系列@Ruby星球 Ruby 一组很棒的 Ruby(编译器、解释器、虚拟机、解析器、文档生成器、版本管理器等) 欢迎投稿。 缺什么吗? 发送拉取请求。 谢谢。 笔记: :gem_stone: 代表 RubyGems 页面,...

    guard-annotate:笔记

    在 Ruby 1.8.7、1.9.x、2.1.x 上测试 安装 安装宝石: gem install guard - annotate 将 gem 添加到您的 Gemfile 中: gem 'guard-annotate' 通过运行将保护定义添加到您的 Guardfile: guard init annotate ...

    rdio-simple:访问 Rdio Web 服务 API 的简单库

    简单的收音机 一组用于 Rdio 的 Web API 的简单客户端库。 这些用于 Python、PHP、Ruby、Node.js 和 Java 的库实现了与 Rdio 服务对话所需的 OAuth 子集,并且具有...测试套件依赖于ruby-1.9命令来运行 1.9 版的 ru

Global site tag (gtag.js) - Google Analytics