RuboCop の Ruby 3.0 対応

構文解析まわりは Ruby 3.0 リリース以前に概ね対応されていると思うので、うまく解析できなかったらバグの可能性があります。その場合の初手としては Parser gem を 3.0.0.0 以上にすると解決するかもしれないので、bundle update parser をしても再現するか見てみてください。

ここでは Ruby 3.0 リリース前後のクリスマスあたりから年末年始にかけて実装していた既存 Cop への対応と、新たな Cop について書いておきます。RuboCop 1.7 に入っているものもあれば、今後のリリースに含まれていくものも併せて記しておきます。

Frozen Regexp, Range リテラル対応

Ruby 3.0 では Regexp リテラルならびに Range リテラルについて、デフォルトで frozen になりました。それにともない定数代入に対する Cop である Style/RedundantFreeze cop と Style/MutableConstant cop について、Ruby 3.0 でのそれらリテラルの定数代入で freeze が不要なことを検知できるようにしました。

github.com

これは早めに入れておきたかったことから最優先で対応していたもので、RuboCop 1.7 に含まれています。

Hash#except 対応

Hash#except ならびに ENV#except に置換可能なケースを検出する Style/HashExcept cop を追加しました。Ruby 3.0 以上のみ有効な Cop ですが、Hash#except は Active Support からインポートされたメソッドなので、Active Support を使っている Ruby 3.0 の Rails プロジェクトなんかで、より効果を発揮するかもしれません。

github.com

Ruby 3.0 構文解析を正式サポート

Ruby 3.0 に正式対応した Parser 3.0.0.0 以上を要求するようにしました。

github.com

以下のような警告が出るひとは Parser のバージョンを上げてみてください。

% ruby -v
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
% rubocop
warning: parser/current is loading parser/ruby30, which recognizes
warning: 3.0.0-dev-compliant syntax, but you are running 3.0.0.
warning: please see
https://github.com/whitequark/parser#compatibility-with-ruby-mri.

Endless Method Definition のスタイル cop

本エントリ中でこの Cop だけは自分の実装ではないもの (ざっとレビューはしている) 。これはコントリビューターのダニエルが提案している Cop で、Endless Method Definition に対するスタイルをチェックする Cop です。Ruby 3.0 リリースイベントでも Endless Method Definition でメソッド本体を複数行で書いていた ko1 さんに、mame さんが1行で書くことを想定していたというやりとりがありましたが、この Cop はデフォルトで1行定義であれば許可するといった振る舞いになる方向です。

github.com

Dir.glob の結果がソート済みになる対応

Ruby 3.0 から Dir.glob の結果がファイルシステムに依存せずソート済みになることに対応しました。Ruby 3.0 だと Dir.glob のあとに sort を加える警告をしません。将来 RuboCop が Ruby 3.0 以上のみのサポートになったら、この Lint/NonDeterministicRequireOrder cop は非推奨警告して削除する予定です。

github.com

上記と対になる新規 Cop で、Dir.globに続いて sort がされている場合に冗長な sort を消します 。

github.com

元々 Lint/NonDeterministicRequireOrder cop の提案がインターネットの海の向こうから来たときに、Dir.glob の結果がソートされないことで困るユースケースがあることを、amatsuda さんにパッチ会で相談したのを覚えていたので、本家がデフォルトでソート済みになったのを受けて対応しようと思っていたのを行った流れです。

lambda の引数にブロックリテラルを使わず Proc 引数を渡す警告

Ruby 3.0 で lambda(&proc { do_something }) のように、lambda の引数にブロックリテラルを使わず Proc 引数を渡している場合の警告をエミューレーションする Cop を追加しています。オートコレクトについて少し悩んだのですが、既存の振る舞いを維持する形にしました。

github.com

余談ですが、このパッチが 2021 年の書き初めです。

NIL, TRUE, FALSE, Ramdom::DEFAULT定数の削除や非推奨への対応

NIL, TRUE, FALSE, Ramdom::DEFAULT といった定数が削除、非推奨されることに対応しておこうと思っていたのですが、まとめて非推奨定数を検知できる Cop として追加の提案をしておきました。

github.com

Numbered Parameter への代入がエラーになることへの対応

Numbered Parameter への代入は Ruby 2.7 では警告、Ruby 3.0 でエラーになるようになりました。Ruby 2.7 の警告をエミュレーションした Cop を追加しました。ただのエミュレーションではない拡張ポイントとして、Numbered Parameter は _1 から _9 までで、_0_10 以上はただのローカル変数のようでしたが、Naming 部署の Cop として一律警告するようにしました。この拡張があるため Lint ではなく Naming 部署に置いたという流れです。

github.com


RuboCop の Ruby 3.0 サポートについて、引き続き対応していく予定です。

また、OSS 活動を支援してくれるスポンサーを GitHub Sponsors で募っていますので、こちらもどうぞよろしく。

github.com

それではハックを続けましょう。