神奇的rubocop

很早就听说过在 Ruby 界有一个 Ruby Style Guide,但我也只是随便翻了一下,感觉一时半刻太难记了。

上班之后,有位同事对风格比较执着,给我做 code review 的时候,经常会指出我写的代码里的一些风格问题。后来又一次,他扔了一句

跑一下 bin/rubocop

我跑完之后,即神奇的事情就发生。Rubocop 这个 gem 的功能就是,把整个项目的代码都按照 Ruby Style Guide 的要求检查一遍,依次列出不符合风格的地方。一些简单的风格问题,比如换行、空行等问题,直接就替我改过来了。

下图就是 bin/rubocop 的依次运行结果。

rubocop

检查出来的第一个问题是关于 each 的用法。我原来是这么写的

@user.products.each { |product| product.remove! }

但是 Ruby Style Guide

Use the proc invocation shorthand when the invoked method is the only operation of a block.

# bad
names.map { |name| name.upcase }

# good
names.map(&:upcase)

也就是说,我应该改成

@user.products.each(&:remove!)

第二个问题是关于 !!,我原来是这么写的

def locked?
  !!self.locked_at
end

但是 Ruby Style Guide

!! converts a value to boolean, but you don’t need this explicit conversion in the condition of a control expression; using it only obscures your intention. If you want to do a nil check, use nil? instead.

# bad
x = 'test'
# obscure nil check
if !!x
  # body omitted
end

# good
x = 'test'
if x
  # body omitted
end

第三和第四个问题是关于 self

但是 Ruby Style Guide

Avoid self where not required. (It is only required when calling a self write accessor, methods named after reserved words, or overloadable operators.)

# bad
def ready?
  if self.last_reviewed_at > self.last_updated_at
    self.worker.update(self.content, self.options)
    self.status = :in_progress
  end
  self.status == :verified
end

# good
def ready?
  if last_reviewed_at > last_updated_at
    worker.update(content, options)
    self.status = :in_progress
  end
  status == :verified
end

所以我应该改成

def locked?
  locked_at
end

有了这个神奇的 gem,每次写完大功能,提 PR 之前,跑一次 bin/rubocop,有错就改,应该是 Ruby Style Guide 的正确学习方法。

· rails