RuboCop 0.78.0 リリース解説

RuboCop 0.78.0 がリリースされたので、概要をざっくり記しておきます。

github.com

今回は新たな cop の追加と LineLength cop の部署変更が行われたリリースです。

LineLength cop の部署変更については自分が入れた Breaking Change で、LineLength の警告への解決は行の折り返しや本意でない名前への変更といったケースがほとんどで、Metrics として捉えたいロジックの複雑性といったものを解決するものではないのが理由です。そのため Layout 部署に移動しています。

また Layout 部署への移動に対して今回含めていない対応として、LineLength へのデフォルト値の変更といったものがあります。こちらはデフォルト値とその提案をどうするかを検討しているところ。

pocke さん作の mry も対応版がリリースされているので、コマンドラインでの機械的解決をしたい人 (基本的にそうだと思う) におすすめです。

また今回追加された cop は Lint/NonDeterministicRequireOrder cop です。以下は提案された PR に記された bad ケースと good ケースです。

# bad
Dir["./lib/middleware/*.rb"].each do |file|
  require file
end

# good
Dir["./lib/middleware/*.rb"].sort.each do |file|
  require file
end

どうやら開発環境と本番環境のファイルシステムの差異で Dir['*/path/*.rb'] の戻り値の並び順が異なったことが起因して問題になったために提案されたとのこと。いまのところ対象の要素を require の引数にするとき限定でのためコアで持っても良い cop かなといった感じで入っています。

このあたりの経緯は 2019年11月のパッチ会のエントリにも記しているので興味があれば参照してください。

koic.hatenablog.com

その他に追加オプションや多くのバグ修正が含まれています。何かあればフィードバックお待ちしています。

平成Ruby会議01

平成Ruby会議01でクロージングキーノートでの登壇をした。当日のスライドは以下。

RuboCop Faker 周辺の話は RubyKaigi 2020 の LT 向けにプロポーザルを出そうかなと思っていた種で、今回キーノート枠を頂いていたことで自分が影響されたものを引用しようと、マーチンファウラーの Bliki やら、 Uncle Bob がパッケージングしたオブジェクト指向設計原則のひとつやら、ソフトウェアエンジニアリング方面からカオスレポート (データが古いですが) など持ち寄って Ruby という幹への肉付けをしたものにした。

本編では割愛しているけれど、kdmsnr さんが訳している Bliki (ja) はいま読んでも面白いと思うのでおすすめ。名作は時を越える。

bliki-ja.github.io

今回、キーノートの依頼があった際にオープニングキーノートとして金子さんの名前を伺っていたので、真っ先に思い出したのが本編でもメンションした京都での RubyKaigi 2016 だった。2016 年あたりは OSS により姿勢が傾いていった頃で、金子さんに紹介してもらった yahonda さんに Oracle enhanced adapter のイシューを相談させてもらって会期中にハックしてもらったり、Connction adapters の下の話をしたりしていた (のちの沖縄Ruby会議 02 でのプレゼンネタに繋がる) 。それが気がつけば3年前。それまでをふりかえる良い契機になりました。

また平成.rbとは TokyuRuby会議 13で、かしまさんと意気投合して参加させてもらったりした流れもあったりで、こうやって地域の Ruby コミュニティでの人の重なりが広がって熱量が高まっていくのはいいものだなあと思ったりしました。スタッフのみなさんはじめ、ありがとうございました!

f:id:koic:20191218154003j:plain:w400

Ginza.rb 第78回

Ginza.rb 第78回だった。会場はメドピアさん。

何が一番の収穫だったかというと Ruby 2.7 に含まれる Numbered parameters について、名前重要なはずなのに引数順序の数字で表現されるのがうーんと思っていたところ「Ruby は Web アプリケーションを書く言語ではなくて、スクリプト言語だから」という初心というか出自を思い出させてくれるコメントを聞けたこと。

例えば書き捨てのときは如何にもスクリプト言語っぽい機能となるという考え方はなるほどと思ったのと、それはそれとしてメンテナンス対象のエンタープライズアプリケーションなどのコードでは名前がついていてもらいたいものだけれど、ユーザーのコンテキストによって選択肢が生まれるのはあるいは面白いのかもしれない。

あとはパターンマッチへの期待や、キーワード引数の分離への破壊的変更についてとか個人的に盛り上がったネタだった。ところどころ tmtms さんのアドベントカレンダーが会を先取りしていたかのようにまとまっていて便利だった。

qiita.com

Rails/OSSパッチ会 2019年11月

Rails/OSSパッチ会 2019年11月を開催した。

いくつか行なっていたことがあり、まずは RuboCop Railsマイグレーションdecimal 型を指定する際に precisionscale を必須にしないと警告を出す提案が来ていて、Active Record メンテナーの kamipo さんに相談をしていたりした。

Active Record では scale オプション値によって、Type::DecimalType::DecimalWithoutScale が返るようになっていて Type::DecimalWithoutScale の方は消したいというお気持ちの FIXME として記されていることを教えてもらった。

if scale == 0
  # FIXME: Remove this class as well
  Type::DecimalWithoutScale.new(precision: precision)
else
  Type::Decimal.new(precision: precision, scale: scale)
end

https://github.com/rails/rails/blob/v6.0.2.rc1/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb#L656-L661

この辺りをヒントに Type::DecimalWithoutScale が誕生しないような cop としてコメントをしたのが以下。

github.com

松田さんには RuboCop core に提案されている PR について相談していた。内容としては Dir.glob(path) が返すパスの配列の順序はファイルシステムに依存しており、開発とプロダクションでファイルシステムが異なると結果が変わって困ることがあったというもの。解決策としては Dir.glob(path).sort を書くといったものだが、Dir.glob(path) の振る舞いを変更する提案は breaking change の話になるし、仮に Dir.glob(path, sort: true)Dir.glob(path, mode: :sort) といったオプションを提案したとしても Dir.glob(path).sort の方が短くてインタフェースとしてどうだろうかという話をしていたりした。とりあえず提案されている cop としては Dir.glob(path) の結果を元に require の順序を一意にしたいという状況に限定されているので、このあとマージを前提にレビューをしようかなと思っている。

QWYNG さんからは Rails アプリケーションのコントローラで Style/RedundantReturn偽陰性があることをフィードバックしてもらって、どのように対処しようかという話をしたりしていた。以下の PR として開いてもらったので、順番に見ていきたいと思う。

github.com

自分としても RuboCop 1.0 までに提案したい breaking change となる手元のパッチがあるので、提案の根拠をコミットメッセージにしるしていたり rebase してコンフリクトを解消したりしていた。

次回のパッチ会は 12月18日(水) です。Ruby 2.7 のリリース前に開催した方が、万が一何か見つけた時に良さそうといった日程になっています。

RuboCop 0.77.0 リリース解説

RuboCop 0.77.0 がリリースされたので、概要をざっくり記しておきます。

今回は cop 名やオプション名などで、以下の理由から多くの名称変更が加えられたリリースです。

  • 例えば UnneededRedundant など cop 名に対してバラバラに使われていた用語を Redundant に統一するなど、用語の統一
  • WhitelistBlanklist といった用語がオプション名に使われていたのを、Allow listDeny list 的な用語に刷新した、潮流の反映

いずれもユーザー定義の .rubocop.yml への breaking change にあたるため、RuboCop 1.0 より前に適用しておきたかったうちのものがリリースされた形です。

このうち部署名変更については、pocke さんが mry を RuboCop 0.77 対応してくれているので RuboCop 0.76 からの移行であればそちらを活用すると便利かもしれません (pocke さんいつもありがとうございます!) 。なお、0.60.0 から 0.76.0 の間は現在 TODO となっているのと、オプション名は現在未対応のようで、それぞれ PR を出してみて良いかもしれません。

github.com

known issue としては Style/TrivialAccessors cop に対するオプション名 AllowedMethodsAllowedMethodtypo しているものがあり、PR がマージされています

なお、今回のリリースで新たな cop は導入されていないため、部署名の変更以外はバグ修正がメインとなっています。

最後におまけ情報。マイルストーンに対するイシューがいくつか残っているので、そのあたりの動きにも影響されると思いますが、RuboCop 1.0 はクリスマス前後にリリースされるかもしれません。

github.com

マイルストーンとしては、それまでのタイムアタックでやることいっぱいなのですが、乞うご期待。

RuboCop Rails 2.4.0 リリース解説

RuboCop 2.4 系の最初のリリースとなる 2.4.0 をリリースしたので、概要をざっくり記しておきます。

github.com

Rails 部署に新たに追加された cop は以下の4つ。

Rails/ApplicationController cop

Rails/ApplicationRecord の Controller 版。

# bad
class MyController < ActionController::Base
end

# good
class MyController < ApplicationController
end

Rails/ApplicationMailer cop

Rails/ApplicationRecord の Mailer 版。ApplicationMailer クラス層が導入された Rails 5.0 以上のアプリケーションが検査対象となる。

# bad
class MyMailer < ActionMailer::Base
end

# good
class MyMailer < ApplicationMailer
end

Rails/RakeEnvironment cop

Rails アプリケーションにおける Rake ファイルのタスク定義で :environment タスクに依存しているか検査する。

# bad
task :foo do
end

# good
task foo: :environment do
end

:environment タスクへの依存を失念するというケースがなるほどの一方で、振る舞いを変える可能性があるため auto-correct はデフォルトで unsafe としている。

Rails/SafeNavigationWithBlank cop

以下について検査する cop で少し説明が必要なので後述。

# bad
do_something if foo&.blank?
do_something unless foo&.blank?

# good
do_something if foo.blank?
do_something unless foo.blank?

これは以下のようにレシーバーが nil の場合に safe navigation operator で blank? メソッドを呼び出した結果 falsy になるので、意図に反している可能性を示唆する cop となる。

nil.blank? #=> true
nil&.blank? #=> nil

そのため auto-correct はデフォルトで unsafe としている。

Rails/UnknownEnv の拡張

Rails/UnknownEnv について以下のケースも検知するようになった。

 # bad
 Rails.env.proudction?
+Rails.env == 'proudction'

 # good
- Rails.env.production?
+ Rails.env == 'production'

Rails/FilePath cop のデフォルトスタイル変更

このリリースでの大きな変更として Rails/FilePath のデフォルトの EnforcedStyle の変更がある。これまでの badgood が反転してデフォルトの EnforcedStyle: slashes では以下のようになる。

# bad
Rails.root.join('app', 'models', 'goober')
File.join(Rails.root, 'app/models/goober')
"#{Rails.root}/app/models/goober"

# good
Rails.root.join('app/models/goober')

もともと Windows 環境でのファイルパスセパレータとの互換を考慮して配列引数で渡しましょうといった流れだったようだが、Rails.root の戻り値となる Pathname オブジェクトはファイルパスセパレータに対する環境差異を吸収してくれているので、文字列引数で問題がなかった。また、生成する文字列の数も減らせそう、かつ、引数はひとつで固定されるなどの理由からデフォルトを変更した。これは Rails/OSS パッチ会で松田さんからデフォルト変更の提案があったことがきっかけになっている。

もし従来のスタイルの方が好ましい場合は EnforcedStyle: arguments を指定してください。

その他に Rails/ReversibleMigration, Rails/EnumHash, Rails/Presence, Rails/SaveBang といった cop へのバグ修正が含まれています。

エンジョイ!

Asakusa.rb 第541回

YARD の以下の PR で言及されていた irb モジュールへの言及について糸柳メンバーに相談しに行っていた。

github.com

少し詳細に入ると、YARD は slex という irb の内部 API に依存した作りになっていて、slex が消えたことについて YARD が困っている話をしたり (内部 API に依存するのはやめましょう事例) 、ruby/ruby リポジトリを slex で grep したら消し忘れっぽい定数があったことをフィードバックしたりしていた (削除された) 。Asakusa.rb べんり。

あとはモリスさんに RWC でカニの時期の松江体験が素晴らしかったという活動報告をしたりして帰宅した。