语法 (Syntax)

语法 (Syntax)

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

  #  错误
  for elem in arr do
    puts elem
  end

  #  正确
  arr.each { |elem| puts elem }
  • 单行的情况下, 尽量用 {...} 而不是 do...end。
    多行的情况下避免用 {...}.
    对于 “control flow” 和 “方法定义”(举例: 在 Rakefiles 和某些 DSLs 里) 总是用 do...end。
    方法连用(chaining)时 避免使用 do...end 。[link]
  names = ["Bozhidar", "Steve", "Sarah"]

  #  正确
  names.each { |name| puts name }

  #  错误
  names.each do |name| puts name end

  #  正确
  names.each do |name|
    puts name
    puts 'yay!'
  end

  #  错误
  names.each { |name|
    puts name
    puts 'yay!'
  }

  #  正确
  names.select { |name| name.start_with?("S") }.map { |name| name.upcase }

  #  错误
  names.select do |name|
    name.start_with?("S")
  end.map { |name| name.upcase }

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

  • 尽可能用短的自赋值操作符 (self assignment operators)。[link]
  #  错误
  x = x + y
  x = x * y
  x = x**y
  x = x / y
  x = x || y
  x = x && y

  #  正确
  x += y
  x *= y
  x **= y
  x /= y
  x ||= y
  x &&= y
  • 避免用分号。 除非是单行 class 定义的情况下。 而且当使用分号时, 分号前面不应该有空格。[link]
  #  错误
  puts 'foobar'; #  多余的分号
  puts 'foo'; puts 'bar' #  两个表达式放到一行

  #  正确
  puts 'foobar'

  puts 'foo'
  puts 'bar'

  puts 'foo', 'bar' #  this applies to puts in particular
  • :: 的使用场景是引用常量,(比如
    classes 和 modules 里的常量) 以及调用构造函数 (比如 Array() 或者 Nokogiri::HTML())。
    普通方法调用就不要使用 :: 了。[link]
  #  错误
  SomeClass::some_method
  some_object::some_method

  #  正确
  SomeClass.some_method
  some_object.some_method
  SomeModule::SomeClass::SOME_CONST
  SomeModule::SomeClass()
  • 尽量避免用 return。
    [link]
  #  错误
  def some_method(some_arr)
    return some_arr.size
  end

  #  正确
  def some_method(some_arr)
    some_arr.size
  end
  • 条件语句里不要用返回值[link]
  #  错误 - shows intended use of assignment
  if (v = array.grep(/foo/))
    ...
  end

  #  错误
  if v = array.grep(/foo/)
    ...
  end

  #  正确
  v = array.grep(/foo/)
  if v
    ...
  end
  • 请随意用 ||= 来初始化变量。
    [link]
  #  把 name 赋值为 Bozhidar, 仅当 name 是 nil 或者 false 时
  name ||= 'Bozhidar'
  • 不要用 ||= 来初始化布尔变量。
    (想象下如果值刚好是 false 会咋样.)[link]
  #  错误 - would set enabled to true even if it was false
  enabled ||= true

  #  正确
  enabled = true if enabled.nil?
  • 当调用 lambdas 时,明确使用 .call。
    [link]
  #  错误
  lambda.(x, y)

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

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

  #  错误
  bluths.map { |bluth| bluth.occupation }
  bluths.select { |bluth| bluth.blue_self? }

  #  正确
  bluths.map(&:occupation)
  bluths.select(&:blue_self?)
  • 当调用当前实例的某个方法时, 尽量用 some_method 而不是 self.some_method。[link]
  #  错误
  def end_date
    self.start_date + self.nights
  end

  #  正确
  def end_date
    start_date + nights
  end

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

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