RuboCop 0.79.0 リリース解説

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

github.com

今回は RoboCop 1.0 に向けた新たな Enable オプションへの新たな値 pending が導入されたのと、Ruby 2.7 の初期サポートが含まれたリリースです。

ちなみにレビュー以外での自分の関わりは、11のバグフィックスうち7つを手がけていました。

New features

#7296: Recognize console and binding.console (rails/web-console) calls in Lint/Debuggers. ([@gsamokovarov][])

Lint/Debuggers cop で web-console での consoleデバッグ用のメソッドとして検知するようにしています。ただ、TTY ライブラリで使われるような名前なので、そのあたりの衝突が懸念されていたところリリースされていたものでした。実際のところは Rails で衝突しているようでリバートされるかもしれません。

github.com

#7567: Introduce new pending status for new cops. ([@Darhazer], [@pirj])

RuboCop 1.0 に向けて、.rubocop.yml の Enable オプションに、新たな値 pending が導入されました。 初期リリースされた新たな cop でままある誤検知への対策で、リリース初期の cop は pending というステータスではじまりデフォルトでは実行されない流れになります。

たしか Enable: false だけだと無効化の意味合いが曖昧ということで新たに追加されたステータスです。

Bug fixes

#7193: Prevent Style/PercentLiteralDelimiters from changing %i literals that contain escaped delimiters. ([@buehmann][])

Style/PercentLiteralDelimiters での問題を直しています。これなぜか自分の環境では再現できかったんですよね。

#7590: Fix an error for Layout/SpaceBeforeBlockBraces when using with EnforcedStyle: line_count_based of Style/BlockDelimiters cop. ([@koic][])

Style/BlockDelimiters cop の EnforcedStyleline_count_based の際にエラーになる問題を直しました。これは Layout/SpaceBeforeBlockBraces cop 中で Style/BlockDelimiters cop の設定を参照している部分のコードに対してテストが足りていないことで、見落としていたバグでした。

#7569: Make Style/YodaCondition accept __FILE__ == $0. ([@koic][])

__FILE__ == $0 はいずれも事実上の読み取り専用ということで、Style/YodaCondition cop で検知しなくても良いだろうと受け入れるようにしました。

#7576: Fix an error for Gemspec/OrderedDependencies when using a local variable in an argument of dependent gem. ([@koic][])

gemspec で以下のように add_dependency をループ処理内に書くなどしたときにエラーになるのを防ぎました。

Gem::Specification.new do |s|
  %w[foo bar].each { |dep| s.add_dependency dep }
  s.add_dependency 'baz'
end

そもそもループ処理などではなく、一律でフラットに書くという cop がレビュー中で提案されています。

#7595: Make Style/NumericPredicate aware of ignored methods when specifying ignored methods. ([@koic][])

Style/NumericPredicate cop で IgnoredMethods オプションが効いていなかった問題を直しています。

#7607: Fix Style/FrozenStringLiteralComment infinite loop when magic comments are newline-separated. ([@pirj][])

# frozen_string_literal: true でループするようなバグがあったようです。自分の環境だと再現がうまくできなかったけれど何だったのだろう。

#7602: Ensure proper handling of Ruby 2.7 syntax. ([@drenmi][])

Ruby 2.7 の初期サポートが入りました。まだバグがあるようで、新たな問題があればフィードバックをください。

github.com

#7620: Fix a false positive for Migration/DepartmentName when a disable comment contains a plain comment. ([@koic][])

# rubocop:disable Style/SafeNavigation # support Ruby < 2.3.0 のように、disable コメントに続いてコメントが書かれているようなケースでの偽陽性を直しました。

#7616: Fix an incorrect autocorrect for Style/MultilineWhenThen for when statement with then is an array or a hash. ([@koic][])

Style/MultilineWhenThen cop で以下のような auto-correct による syntax の破壊を直しました。

% cat example.rb
case condition
when foo then {
    key: 'value'
  }
end

% ruby -c example.rb
Syntax OK

% bundle exec rubocop -a --only Style/MultilineWhenThen
(snip)

% cat example.rb
case condition
when foo {
    key: 'value'
  }
end

% ruby -c example.rb
example.rb:3: syntax error, unexpected ':', expecting '}'
    key: 'value'
example.rb:4: syntax error, unexpected '}', expecting end-of-input

#7628: Fix an incorrect autocorrect for Layout/MultilineBlockLayout removing trailing comma with single argument. ([@pawptart][])

以下のようなケースで auto-correct によりブロック引数のコードが破壊される問題が直されています。

# Before
[[1, 2, 3], [3, 4, 5]].each do |a,
  |
  p [a]
end
# After
[[1, 2, 3], [3, 4, 5]].each do |a|
  p [a]
end

#7627: Fix a false negative for Migration/DepartmentName when there is space around : (e.g. # rubocop : disable). ([@koic][])

disable コメントは、rubocop : disable のように : の前後にスペースを入れても有効だったものが検出できなかった問題を直しました。この振る舞い知らなかった。

Changes

#7287: Style/FrozenStringLiteralComment is now considered unsafe. ([@buehmann][])

fstring のマジックコメントを書くとコードとしての互換性がなくなっている可能性があるため、unsafe にマークされました。


多くのユーザーにとってはバグフィックスがメインになると思うので、アップデートしてみてください。

AirPods Pro が届いた

今月のパッチ会のときに yahonda さんから AirPods Pro の体験が良いと聞いたので注文していた AirPods Pro が届いた。

Apple AirPods Pro

Apple AirPods Pro

  • 発売日: 2019/10/30
  • メディア: エレクトロニクス

実際のところアクティブノイズキャンセリングの効果が素晴らしくて、イヤホンの装着によって「ふっ」と音楽を聞く体勢に入る無音の世界に切り替わって、雑音のある現実世界とノイズキャンセリングされた音楽の世界との往復ができるという体験は素晴らしかった。

このアクティブノイズキャンセリングは、雑音のない世界に入って集中力を高めたプログラミングをするのにも良いと思うので、BGM を愛用するプログラマーにおすすめだと思う。

Ruby 2.7 リリースパーティー

Ruby 2.7 リリースパーティーに行った。会場は Speee さん。

松田さんの MC で Ruby コミッターによる Ruby 2.7 制作秘話から始まり、そのままパーティーへという流れだった。

個人的には Ruby 3 に向けた型について、ruby/ruby-signature で集められている型定義ファイル rbs (Steep が対応) と sorbet/sorbet-typed で集められている型定義ファイル rbi (Sorbet が対応) で行われていることが重複している点として気になっていたので、パーティーで Matz や soutaro さんにその辺りを聞きたいと思っていて聞いたりした。いちおう型チームの中では rbs に寄せていくということで話ができているらしく、Sorbet の方でも rbi 以外に rbs のサポートもしていくのではといった感じだった。なので型定義は rbs が公式であり、処理系として Steep と Sorbet を選択していくというのが現在と近未来になりそう。その他、Ruby 4.0 のコンセプトである『Smarter, Faster』について話を聞いたりして、今後の Ruby への気持ちを高めることができる良い会でした。

またこのパーティーでは hasumikin のお燗番という豪華な熱燗提供でした。ごちそうさまでした。楽しかったです。

RuboCop Performance 1.5.2, RuboCop Rails 2.4.1, RuboCop Minitest 0.5.1 をリリースした

RuboCop Performance 1.5.2, RuboCop Rails 2.4.1, RuboCop Minitest 0.5.1 をまとめてリリースした。

github.com

github.com

github.com

これらの master ブランチにあるバグフィックスについて、年またぎで溜めていてもなのでクリスマスということでリリースしておいた。新機能は含んでいないバグフィックスが主なので同系のバージョンを使っているようであれば (いるようでなくても) bundle update しておくと良いと思います。

特に深刻な問題がなければ自分がメインメンテナーをしている RuboCop extension gems としては、年内のリリース納めです。メリークリスマス。

RubyGems 3.1のローカル非推奨警告を消す

RubyGems 3.1 がリリースされたのでローカル環境の RubyGems をアップデートした。

% gem update --system
% gem -v
3.1.2

アップデート後、gem i <gemname> や gem の差分を見る gemdiff などを使った時に以下のような警告の川が流れるようになった。

実際 Gem::Specification#rubyforge_project= が使われている gemspec に関してかなりの量が自分のローカルの場合は表示されていたので、上記は抜粋となる (古めのリポジトリを対象としているので、それも影響しているかもしれない) 。

Gem::Specification#rubyforge_project= called from /Users/koic/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/specifications/letter_opener-1.7.0.gemspec:16.
NOTE: Gem::Specification#rubyforge_project= is deprecated with no replacement. It will be removed on or after 2019-12-01.
Gem::Specification#rubyforge_project= called from /Users/koic/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/specifications/letter_opener-1.6.0.gemspec:16.

警告を消すひとつとしては gem pristine <gemname> すれば良い。

% gem pristine letter_opener

(snip)
NOTE: Gem::Specification#rubyforge_project= is deprecated with no replacement. It will be removed on or after 2019-12-01.
Gem::Specification#rubyforge_project= called from /Users/koic/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/specifications/letter_opener-1.7.0.gemspec:16.
NOTE: Gem::Specification#rubyforge_project= is deprecated with no replacement. It will be removed on or after 2019-12-01.
Gem::Specification#rubyforge_project= called from /Users/koic/.rbenv/versions/2.4.9/lib/ruby/gems/2.4.0/specifications/letter_opener-1.6.0.gemspec:16.
Restoring gems to pristine condition...
    exists /Users/koic/src/github.com/ryanb/letter_opener
Restored letter_opener-1.6.0
    exists /Users/koic/src/github.com/ryanb/letter_opener
Restored letter_opener-1.7.0

今回量が多かったので以下のようなワンライナーをバックグラウンドで実行しておいた。

% ruby -e 'Gem::Specification.map(&:name).uniq.each {|spec_name| puts "* gem pristine #{spec_name}"; `gem pristine #{spec_name}`}'

このワークアラウンドだと警告の出ていない gem についても gem pristine を実行することになるが、年末の大掃除ということでまとめて適用しておいた。bundle pristine で対処できるかなと思ったらそうではなかったために書いたワークアラウンドなので、もっとうまいやり方があると思う。

(2019.12.20追記)

hsbt さんからコメントをもらう (いつもありがとうございます!) 。upstream でまだ非推奨 API が使われているようであればパッチを送ると良さそう。

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