Ruby 3.1を使ってRuboCopでエラーが起きた場合の対処

先日、Ruby 3.1 で起きる each_conseach_slice の非互換について記しましたが、RuboCop で非互換の影響を受ける部分とその対処について記しておきます。

koic.hatenablog.com

対象となる組み合わせは Ruby 3.1 と RuboCop 1.22.2 以下です。

RuboCop 1.22.2 までは以下のパッチが当たっていません。

github.com

そのため、Layout/BlockAlignment cop が有効になっている場合は、Ruby 3.1 での rubocop コマンドの実行で以下のエラーが起きえます。

      # ./lib/rubocop/cop/layout/block_alignment.rb:97:in `start_for_block_node'
      # ./lib/rubocop/cop/layout/block_alignment.rb:82:in `on_block'
      # ./lib/rubocop/cop/commissioner.rb:100:in `public_send'
      # ./lib/rubocop/cop/commissioner.rb:100:in `block (2 levels) in trigger_responding_cops'
      # ./lib/rubocop/cop/commissioner.rb:160:in `with_cop_error_handling'
      # ./lib/rubocop/cop/commissioner.rb:99:in `block in trigger_responding_cops'

(デフォルトで有効になっている Cop なので、遭遇率はそれなりにあるかもしれません。)

この問題に遭遇した場合の対処方法を列挙します。

1. RuboCop 1.22.3 以上にアップグレードする

これが本手です。問題が解決されている RuboCop 1.22.3 以上にアップグレードしてください。

2. Layout/BlockAlignment cop を無効にする

.rubocop.yml へのワークアラウンドとして、.rubocop.yml に以下を指定してください。

Layout/BlockAlignment:
  Enabled: false

RuboCop へのユーザーフィードバック にあったように、Ruby 2.4 サポートをしたい場合は RuboCop 1.12 までしかアップグレードできません。こういったアップグレードできない事情がある場合のひとつの選択肢になります。

3. モンキーパッチをあてる

例示しないのですが upstream の修正パッチ 同様のモンキーパッチをアプリケーションで当ててください。将来的に実装が変わる可能性があるため、おすすめしないのですが Ruby 2.4 と Ruby 3.1 を同時にサポートして Layout/BlockAlignment cop を有効にしたいケースの選択肢になります。

その他

いちおう他にも CI で問題を解決するという手段もありますが、本手としては RuboCop 1.22.3 以上にアップグレードするになります。また、Ruby 3.1 での each_cons の挙動の変更についてフィードバックを重ねるというのも考えはしたものの、each_cons の挙動変更自体はユーザーにとって自然な方向に向かっていくものだと思うので、付いていける変更具合であれば付いていきたい気持ちから、私の方でフィードバックを重ねることはしないことにしました (もし困っていてお気持ちのある方がいれば、お任せます) 。

なお、この問題について、Rails/OSS パッチ会で osyo さんや amatsuda さんに相談に乗ってもらいました。ありがとうございました。

次回の Rails/OSS パッチ会は 2021年12月21日(火) です。参加は以下の Discord URL までどうぞ。

discord.gg