Ruby编程中的语法使用风格推荐

2019-09-25 09:40:00王冬梅

   

 # bad
  l = lambda { |a, b| a + b }
  l.call(1, 2)

  # correct, but looks extremely awkward
  l = ->(a, b) do
   tmp = a * 7
   tmp * b / 50
  end

  # good
  l = ->(a, b) { a + b }
  l.call(1, 2)

  l = lambda do |a, b|
   tmp = a * 7
   tmp * b / 50
  end

    用 proc 而不是 Proc.new。

  # bad
  p = Proc.new { |n| puts n }

  # good
  p = proc { |n| puts n }

  匿名方法 和 块 用 proc.call() 而不是 proc[] 或 proc.()。

  # bad - looks similar to Enumeration access
  l = ->(v) { puts v }
  l[1]

  # also bad - uncommon syntax
  l = ->(v) { puts v }
  l.(1)

  # good
  l = ->(v) { puts v }
  l.call(1)

    未使用的块参数和局部变量使用 _。它也可以接受通过 _ 来使用(即使它有少了些描述性)。
    这个惯例由 Ruby 解释器以及 RuboCop 这样的工具组织其将会抑制它们的未使用参数警告。

    

# bad
  result = hash.map { |k, v| v + 1 }

  def something(x)
   unused_var, used_var = something_else(x)
   # ...
  end

  # good
  result = hash.map { |_k, v| v + 1 }

  def something(x)
   _unused_var, used_var = something_else(x)
   # ...
  end

  # good
  result = hash.map { |_, v| v + 1 }

  def something(x)
   _, used_var = something_else(x)
   # ...
  end

    使用 $stdout/$stderr/$stdin 而不是 STDOUT/STDERR/STDIN。STDOUT/STDERR/STDIN 是常量,虽然在 Ruby 中是可以给常量重新赋值的(可能是重定向到某个流),但解释器会警告如果你执意这样。

    使用 warn 而不是 $stderr.puts。除了更加清晰简洁,如果你需要的话,
    warn 还允许你抑制(suppress)警告(通过 -W0 将警告级别设为 0)。

    倾向使用 sprintf 和它的别名 format 而不是相当隐晦的 String#% 方法.

 

  # bad
  '%d %d' % [20, 10]
  # => '20 10'

  # good
  sprintf('%d %d', 20, 10)
  # => '20 10'

  # good
  sprintf('%{first} %{second}', first: 20, second: 10)
  # => '20 10'

  format('%d %d', 20, 10)
  # => '20 10'

  # good
  format('%{first} %{second}', first: 20, second: 10)
  # => '20 10'

    倾向使用 Array#join 而不是相当隐晦的使用字符串作参数的 Array#*。

  

 # bad
  %w(one two three) * ', '
  # => 'one, two, three'

  # good
  %w(one two three).join(', ')
  # => 'one, two, three'

    当处理你希望像 Array 那样对待的变量,但是你不确定它是一个数组时,
    使用 [*var] or Array() 而不是显式的 Array 检查。

 

  # bad
  paths = [paths] unless paths.is_a? Array
  paths.each { |path| do_something(path) }

  # good
  [*paths].each { |path| do_something(path) }

  # good (and a bit more readable)
  Array(paths).each { |path| do_something(path) }