読者です 読者をやめる 読者になる 読者になる

SideCI TechBlog

SideCIを作っているアクトキャットのエンジニアによる技術ブログです。


RuboCop 0.44.0 / 0.44.1 のCHANGELOGを読む

f:id:Pocke:20161019163732p:plain

こんにちは、RuboCop大好き!Pockeです。

先日、RuboCopのバージョン0.44.0、0.44.1がリリースされました。

0.44.0 には、多数の機能追加やバグ修正が含まれています。また、0.44.1は1件のバグ修正を含んだhotfixリリースです。

このリリースには、SideCIメンバーによるPull Requestも5個含まれています。 今日はそのCHANGELOGから、気になる新Copを見ていきましょう。

新規Cop追加

Copとは、RuboCopにおいてひとつのルールを指す言葉です。例えば、「インデントが正しいかチェックする」「非推奨メソッドを使っていないかチェックする」などが1つのCopの単位になります。

この章では、0.44.0で新たに追加されたCopをひとつずつ紹介します。

Rails/HttpPositionalArguments

解説

Rails 5からActionController::TestCase::Behaviorの挙動がかわり、以下のようなコードは非推奨になりました。

describe UsersController do
  it '#show' do
    get :show, id: 1
  end
end

get :show, id: 1の部分が非推奨です。 これをget :show, params: {id: 1}の様に書き換える必要があります。

この変更によって、以下のようにparamssessionの両方を区別して扱うことが可能になります。

describe UsersController do
  it '#show' do
    get :show, params: { id: 1 }, session: { user_id: 1 }
  end
end

このCopは、上記のような非推奨になった書き方を検出します。 また、Auto-Correct機能によって自動的に修正することも可能です。

参考: https://til.hashrocket.com/posts/e7a2880383-rails-5-deprecation-warning-for-controller-tests

なお、Rails 5系を使っていない場合、このCopは誤検知を起こしてしまうようです(Rails/HttpPositionalArguments points offenses in rails 4.2 apps · Issue #3629 · bbatsov/rubocop)。 そのような場合には以下のコードを.rubocop.ymlに追記することでこのCopを無効に出来ます。

Rails/HttpPositionalArguments:
  Enabled: false

Metrics/BlockLength

解説

このCopは、一つのブロックに記述される行数をチェックします。 デフォルトでは、1つのブロックに26行以上のコードがある場合、警告を出します。

do_something do
  method1
  method2
  method3

  # ...

  method26
end

上記の様に26行以上のブロックがあるrubyファイルに対してRuboCopを走らせると、以下の警告が発生します。

$ rubocop
Inspecting 1 file
C

Offenses:

test.rb:1:1: C: Block has too many lines. [30/25]
do_something do ...
^^^^^^^^^^^^^^^

1 file inspected, 1 offense detected

この値は、.rubocop.ymlの中で以下のように変更可能です。

Metrics/BlockLength:
  Max: 25 # この値を修正することで変更可能

Rails/DynamicFindBy

解説

このCopは、ActiveRecordが動的に生成するfind_by_*メソッドの使用を検出します。

# Bad
User.find_by_email(email)

# Good
User.find_by(email: email)


# Bad
User.find_by_email_and_name(email, name)

# Good
User.find_by(email: email, name: name)

また、このCopはAuto-Correctをサポートしているため、上記のようなコードを自動で修正することが可能です。

Rails/DelegateAllowBlank

解説

ActiveSupport には委譲をサポートするModule#delegateメソッドがあります。

http://api.rubyonrails.org/classes/Module.html#method-i-delegate

このメソッドはdelegate先のメソッド、変数がnilの場合、通常はNoMethodErrorを発生します。 これを抑制し単にnilを返すようにするオプションとして、allow_nilが用意されています。

class Foo
  delegate :name1, to: :@hoge
  delegate :name2, to: :@fuga, allow_nil: true
end

foo = Foo.new
foo.name1 # raises NoMethodError
foo.name2 # => nil

一方、Railsではvalidationメソッドなどでallow_blankという似たようなオプションが提供されています。

このCopでは、上記の名前の似たオプションを間違えていないかを検査します。

class Foo
  # Good
  delegate :name, to: :@hoge, allow_nil: true

  # Bad
  delegate :age, to: :@fuga, allow_blank: true
end

Style/MultilineMemoization

解説

このCopは、Rubyでメモ化を行う際のスタイルを統一します。

Rubyで複数文の戻り値に対してメモ化を行う際は、以下の二つの書き方が想定されます。 なお、この2つのプログラムは全く同じ挙動を示します。

foo ||= begin
  bar
  baz
end

foo ||= (
  bar
  baz
)

このCopは、この内の前者の書き方(begin-end)に統一します。
現状ではカッコを使用する書き方に統一するルールは用意されていませんが、需要があれば実装するようなので、そのようなコーディングスタイルを使用している方は要望してみてはいかがでしょうか?

まとめ

この記事は以上になりますが、RuboCop 0.44.0ではこの他にも多くの機能追加、バグ修正が行われています。 より詳しい変更を知りたい方は、リリースノートをご覧ください。

Release RuboCop 0.44 (The Birthday Release) · bbatsov/rubocop

また、SideCIでは今すぐRuboCop 0.44.0を利用することが可能です。是非お試し下さい!