神奇的rubocop
很早就听说过在 Ruby 界有一个 Ruby Style Guide,但我也只是随便翻了一下,感觉一时半刻太难记了。
上班之后,有位同事对风格比较执着,给我做 code review 的时候,经常会指出我写的代码里的一些风格问题。后来又一次,他扔了一句
跑一下
bin/rubocop
我跑完之后,即神奇的事情就发生。Rubocop 这个 gem 的功能就是,把整个项目的代码都按照 Ruby Style Guide 的要求检查一遍,依次列出不符合风格的地方。一些简单的风格问题,比如换行、空行等问题,直接就替我改过来了。
下图就是 bin/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 anil
check, usenil?
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 的正确学习方法。