牛骨文教育服务平台(让学习变的简单)
  • 倾向数组及哈希的字面表示法(除非你需要给构造器传入参数)。

    # 差
    arr = Array.new
    hash = Hash.new
    
    # 好
    arr = []
    hash = {}
    
  • 创建元素为单词(没有空格和特殊符号)的数组时,用 %w 而不是 [] 方法。仅当数组有两个及以上元素时才应用这个规则。

    # 差
    STATES = ["draft", "open", "closed"]
    
    # 好
    STATES = %w(draft open closed)
    
  • 当你需要一个符号的数组(并且不需要保持 Ruby 1.9 兼容性)时,使用 %i。仅当数组只有两个及以上元素时才应用这个规则。

    # 差
    STATES = [:draft, :open, :closed]
    
    # 好
    STATES = %i(draft open closed)
    
  • 避免在 Array 和 Hash 字面量中的最后一个元素后面使用逗号。特别是元素同一行的情况下

    # 差 - 方面移动、增加和修改参数,但仍不建议使用
    VALUES = [
           1001,
           2020,
           3333,
         ]
    
    # 差
    VALUES = [1001, 2020, 3333, ]
    # 好
    VALUES = [1001, 2020, 3333]
    
  • 避免在数组中创造巨大的间隔。

    arr = []
    arr[100] = 1 # 现在你有一个很多 nil 的数组
    
  • 当访问数组的首元素或尾元素时,尽量使用 first 或 last, 而非 [0] 或 [-1]

  • 当处理的元素没有重复时,使用 Set 来替代 Array 。 Set 实现了无序、无重复值的集合。 Set 的方法同数组类一样直观,还可像哈希中那样快速查找元素。

  • 尽量用符号来取代字符串作为哈希的键。

    # 差
    hash = { "one" => 1, "two" => 2, "three" => 3 }
    
    # 好
    hash = { one: 1, two: 2, three: 3 }
    
  • 避免使用可变的对象作为键值。

  • 当哈希的键为符号时,使用 Ruby 1.9 的哈希的字面语法。

    # 差
    hash = { :one => 1, :two => 2, :three => 3 }
    
    # 好
    hash = { one: 1, two: 2, three: 3 }
    
  • 但哈希的键有符号也有字符串时,不使用Ruby 1.9的字面量语法。

    # 差
    { a: 1, "b" => 2 }
    
    # 好
    { :a => 1, "b" => 2 }
    
  • 用 Hash#key?。不用 Hash#has_key?。用 Hash#value?。不用 Hash#has_value?。松本提到过已经不推荐使用较长的形式了。

    # 差
    hash.has_key?(:test)
    hash.has_value?(value)
    
    # 好
    hash.key?(:test)
    hash.value?(value)
    
  • 在处理应该存在的哈希键时,使用 Hash#fetch

    heroes = { batman: "Bruce Wayne", superman: "Clark Kent" }
    # 差 - 如果我们打错字的话,我们就无法找到对的英雄了
    heroes[:batman] # => "Bruce Wayne"
    heroes[:supermen] # => nil
    
    # 好 - fetch 会抛出一个 KeyError 来使这个问题明显
    heroes.fetch(:supermen)
    
  • 在使用 Hash#fetch 时,使用第二个参数设置默认值。

    batman = { name: "Bruce Wayne", is_evil: false }
    
    # 差 - 如果我们仅仅使用 || 操作符,那么当值为假时,我们不会得到预期的结果
    batman[:is_evil] || true # => true
    
    # 好 - fetch 在遇到假值时依然正确
    batman.fetch(:is_evil, true) # => false
    
  • 如果求值的代码有副作用或者开销大,尽量用 Hash#fetch 加区块而不是直接设定默认值。

    batman = { name: "Bruce Wayne" }
    
    # 差 - 默认值是立即求值
    batman.fetch(:powers, obtain_batman_powers) # obtain_batman_powers 需要复杂的计算
    
    # 好 - 区块是惰性求职,只有当 KeyError 异常时才执行
    batman.fetch(:powers) { obtain_batman_powers }
    
  • 当需要从哈希中同时获取多个键值时,使用 Hash#values_at

    # 差
    email = data["email"]
    username = data["nickname"]
    
    # 好
    email, username = data.values_at("email", "nickname")
    
  • Ruby 1.9 的哈希是有序的,利用这个特性。

  • 在遍历一个集合时,不要改动它。

  • 当访问集合中的元素时,避免通过 [n] 直接访问,尽量使用提供的方法。这样可以防止你对 nil 调用 []

    # 差
    Regexp.last_match[1]
    
    # 好
    Regexp.last_match(1)
    
  • 为集合提供存取器时,在访问元素之前采用一种替代的形式,从而防止用户访问的下标是 nil

    # 差
    def awesome_things
      @awesome_things
    end
    
    # 好
    def awesome_things(index = nil)
      if index && @awesome_things
        @awesome_things[index]
      else
        @awesome_things
      end
    end