Rubocopが良い

Atomを使うようになってrubyの静的解析ツールである rubocop を常用するようになりました。もう手放せません。
 
Atom では yujinakayama/atom-lint というpackageを利用しており、保存時に自動でチェックされていろいろ捗ります。自分ではソースコード書くときは結構注意していたつもりなのですが、いざ使ってみると沢山指摘されます。

rubocopはjslint並みに厳しく指摘してくれるので、copnameというチェック内容単位でoffにする機能があります。(じゃないとエディタがwarningだらけになる)
 
実はyujinakayama/atom-lint ではこのcopnameが現在は表示されていません。(Add atom-lint.rubocop.showDisplayCopNames #47 by rochefort · Pull Request #82 · yujinakayama/atom-lint で間違った方向のプルリクを出してしまいましたが、作者の方がいい感じでプロト実装中とのこと。copname対応版はもうすぐ出るかと思います。)

.rubocop.yml

各プロジェクトもしくは$HOME 以下に置いておくと対象のcopnameをdisable(無視)することができます。

rubocop.yml 例

# Favor modifier if/unless usage when you have a single-line body.
IfUnlessModifier:
  Enabled: false

# Limit lines to 80 characters.
LineLength:
  Enabled: false

# Use nested module/class definitions instead of compact style.
# NG: module Gem::Search
Style/ClassAndModuleChildren:
  Enabled: false

# Prefere reduce over inject.
Style/CollectionMethods:
    Enabled: false

# Missing top level class documentation comment.
Style/Documentation:
  Enabled: false

# Avoid the use of double negation (!!)
Style/DoubleNegation:
  Enabled: false

# Favor format over String#%.
# NG: url = SEARCH_API % [query, n]
Style/FormatString:
  Enabled: false

# Favor modifier while/until usage when you have a single-line body.
WhileUntilModifier:
  Enabled: false

-D/–display-cop-names オプション

どうやって作るかですが、-D つけるとcopnameを表示してくれるので、これで確認しながらポツポツ追加しています。

❯❯❯ rubocop lib/gem_search/executor.rb
Inspecting 1 file
C

Offenses:

lib/gem_search/executor.rb:14:5: C: Style/MethodLength: Method has too many lines. [14/10]
    def search(query, opts)
    ^^^
lib/gem_search/executor.rb:48:9: C: Style/PercentLiteralDelimiters: %w-literals should be delimited by ( and )
        %w[xdg-open cygstart x-www-browser firefox opera mozilla netscape].find { |comm| which comm }
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lib/gem_search/executor.rb:61:19: C: Style/Blocks: Avoid using {...} for multi-line blocks.
        exts.each { |ext|
                  ^
lib/gem_search/executor.rb:66:7: C: Style/RedundantReturn: Redundant return detected.
      return nil
      ^^^^^^

1 file inspected, 4 offenses detected

–show-cops オプション

全表示。引数にcopnameを指定すると、そいつだけ表示できたりするのにさっき気づきました。次から.rubocop.yml 作るときに利用しようと思います。

❯❯❯ rubocop --show-cops
# Available cops (182) + config for /Users/rochefort/github/dotfiles:
# Type 'Lint' (36):
Lint/AmbiguousOperator:
  Description: Checks for ambiguous operators in the first argument of a method invocation
    without parentheses.
  Enabled: true

Lint/AmbiguousRegexpLiteral:
  Description: Checks for ambiguous regexp literals in the first argument of a method
    invocation without parenthesis.
  Enabled: true
  ...

.rubocop_todo.yml

全部オフできる rubocop_todo.yml を出力する機能ですが、copnameと実コードとの対比が分からんので個人的には使用しないかなといった印象。

❯❯❯ rubocop --auto-gen-config

とやると .rubocop_todo.yml という全部offできるものが出来上がるのでメッセージ通りにすればok。

Run `rubocop --config .rubocop_todo.yml`, or
add inherit_from: .rubocop_todo.yml in a .rubocop.yml file.

rubocop_todo.yml 例

# This configuration was generated by `rubocop --auto-gen-config`
# on 2014-08-14 03:18:18 +0900 using RuboCop version 0.24.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.

# Offense count: 1
# Configuration parameters: Exclude.
Style/FileName:
  Enabled: false

# Offense count: 1
# Configuration parameters: MinBodyLength.
Style/GuardClause:
  Enabled: false

その他オプション

–format offenses

copnameと件数のリスト表示

❯❯❯ rubocop --format offenses

1  Lint/UnusedBlockArgument
1  Style/PerlBackrefs
1  Style/TrailingBlankLines
--
3  Total

–only

copnameで絞って表示

❯❯❯ rubocop --only Style/NumericLiterals
Inspecting 12 files
...........C

Offenses:

spec/spec_helper.rb:33:18: C: Separate every 3 digits in the integer portion of a number with underscores(_).
    "downloads"=>2042859,
                 ^^^^^^^
spec/spec_helper.rb:62:18: C: Separate every 3 digits in the integer portion of a number with underscores(_).
    "downloads"=>1238780,
                 ^^^^^^^
spec/spec_helper.rb:64:26: C: Separate every 3 digits in the integer portion of a number with underscores(_).
    "version_downloads"=>39724,
                         ^^^^^
spec/spec_helper.rb:88:18: C: Separate every 3 digits in the integer portion of a number with underscores(_).
    "downloads"=>15547,
                 ^^^^^

12 files inspected, 4 offenses detected

See Also

共通.rubocop.ymlの管理 - rochefort’s blog
AtomのLinter - rochefort’s blog