语法 (Syntax)

  • 永远不要用 for,除非有非常特殊的理由。
    绝大部分情况都应该用 eachfor 是用 each 实现的(所以你间接加了一层),
    但区别是 - for 不会有新 scope (不像 each) 里面定义的变量外面可见。[link]

    1. arr = [1, 2, 3]
    2. # 错误
    3. for elem in arr do
    4. puts elem
    5. end
    6. # 正确
    7. arr.each { |elem| puts elem }

  • 单行的情况下, 尽量用 {...} 而不是 do...end
    多行的情况下避免用 {...}.
    对于 “control flow” 和 “方法定义”(举例: 在 Rakefiles 和某些 DSLs 里) 总是用 do...end
    方法连用(chaining)时 避免使用 do...end[link]

    1. names = ["Bozhidar", "Steve", "Sarah"]
    2. # 正确
    3. names.each { |name| puts name }
    4. # 错误
    5. names.each do |name| puts name end
    6. # 正确
    7. names.each do |name|
    8. puts name
    9. puts 'yay!'
    10. end
    11. # 错误
    12. names.each { |name|
    13. puts name
    14. puts 'yay!'
    15. }
    16. # 正确
    17. names.select { |name| name.start_with?("S") }.map { |name| name.upcase }
    18. # 错误
    19. names.select do |name|
    20. name.start_with?("S")
    21. end.map { |name| name.upcase }

    有些人会说多行连用(chaining) 用
    {...} 符号 其实也没那么难看, 但他们应该问问自己这代码真的可读吗, 而且 block 里的内容是否可以抽出来弄好看些.

  • 尽可能用短的自赋值操作符 (self assignment operators)。[link]

    1. # 错误
    2. x = x + y
    3. x = x * y
    4. x = x**y
    5. x = x / y
    6. x = x || y
    7. x = x && y
    8. # 正确
    9. x += y
    10. x *= y
    11. x **= y
    12. x /= y
    13. x ||= y
    14. x &&= y
  • 避免用分号。 除非是单行 class 定义的情况下。 而且当使用分号时, 分号前面不应该有空格。[link]

    1. # 错误
    2. puts 'foobar'; # 多余的分号
    3. puts 'foo'; puts 'bar' # 两个表达式放到一行
    4. # 正确
    5. puts 'foobar'
    6. puts 'foo'
    7. puts 'bar'
    8. puts 'foo', 'bar' # this applies to puts in particular
  • :: 的使用场景是引用常量,(比如
    classes 和 modules 里的常量) 以及调用构造函数 (比如 Array() 或者 Nokogiri::HTML())。
    普通方法调用就不要使用 :: 了。[link]

    1. # 错误
    2. SomeClass::some_method
    3. some_object::some_method
    4. # 正确
    5. SomeClass.some_method
    6. some_object.some_method
    7. SomeModule::SomeClass::SOME_CONST
    8. SomeModule::SomeClass()
  • 尽量避免用 return
    [link]

    1. # 错误
    2. def some_method(some_arr)
    3. return some_arr.size
    4. end
    5. # 正确
    6. def some_method(some_arr)
    7. some_arr.size
    8. end
  • 条件语句里不要用返回值[link]

    1. # 错误 - shows intended use of assignment
    2. if (v = array.grep(/foo/))
    3. ...
    4. end
    5. # 错误
    6. if v = array.grep(/foo/)
    7. ...
    8. end
    9. # 正确
    10. v = array.grep(/foo/)
    11. if v
    12. ...
    13. end
  • 请随意用 ||= 来初始化变量。
    [link]

    1. # 把 name 赋值为 Bozhidar, 仅当 name 是 nil 或者 false 时
    2. name ||= 'Bozhidar'
  • 不要用 ||= 来初始化布尔变量。
    (想象下如果值刚好是 false 会咋样.)[link]

    1. # 错误 - would set enabled to true even if it was false
    2. enabled ||= true
    3. # 正确
    4. enabled = true if enabled.nil?
  • 当调用 lambdas 时,明确使用 .call
    [link]

    1. # 错误
    2. lambda.(x, y)
    3. # 正确
    4. lambda.call(x, y)
  • 避免使用 Perl 风格的特殊变量名
    ( 比如 $0-9, $, 等等. ). 因为看起来蛮神秘的. 建议只在单行里使用。建议用长名字, 比如 $PROGRAM_NAME.[link]

  • 当一个方法块只需要 1 个参数,而且方法体也只是读一个属性, 或者无参数的调用一样方法,这种情况下用 &: .
    [link]

    1. # 错误
    2. bluths.map { |bluth| bluth.occupation }
    3. bluths.select { |bluth| bluth.blue_self? }
    4. # 正确
    5. bluths.map(&:occupation)
    6. bluths.select(&:blue_self?)
  • 当调用当前实例的某个方法时, 尽量用 some_method 而不是 self.some_method[link]

    1. # 错误
    2. def end_date
    3. self.start_date + self.nights
    4. end
    5. # 正确
    6. def end_date
    7. start_date + nights
    8. end

    在下面 3 种常见情况里, 需要用, 而且应该用self.:

    1. 当定义一个类方法时: def self.some_method.
    2. 当调用一个赋值方法 (assignment method) 时,左手边 应该用 self, 比如当 self 是 ActiveRecord 模型然后你需要赋值一个属性: self.guest = user.
    3. 指向 (Referencing) 当前实例的类: self.class.