Rails 5.2でActive RecordからArelのメソッドへの移譲に追加されている非推奨警告

Rails 5.2.1 アプリケーションの 24 Pull Requests へのパッチを元にした昨年末の日記の関連。

以下のような警告の川が流れた際には、.arel をレシーバーとして明示的に指定する。

DEPRECATION WARNING: Delegating exists to arel is deprecated and will be
removed in Rails 6.0.
DEPRECATION WARNING: Delegating with to arel is deprecated and will be
removed in Rails 6.0.

24 Pull Requests へのパッチを例にすると以下のような変更になる。

   def self.pull_request_filter
     where("pull_requests.user_id = aggregation_filters.user_id")
     .where("pull_requests.title ILIKE aggregation_filters.title_pattern")
+    .exists.not
-    .arel.exists.not
   end
- it { expect(assigns(:users).with(User.order('pull_requests_count desc').page(0))).to be_truthy }
+ it { expect(assigns(:users).arel.with(User.order('pull_requests_count desc').page(0))).to be_truthy }

導入経緯や対象となるメソッドなどは、この警告が導入された PR に詳しい。

github.com

るろうに剣心 北海道編 (1) を読んだ

剣心華伝か何かに書かれいてた後日談構想の実装ということで次巻以降も読んでいくと思う。

`Layout/EmptyLineAfterGuardClause` cop をデフォルトで有効にした

数日前の話だが Layout/EmptyLineAfterGuardClause cop をデフォルトで有効にする PR を開いてマージされた。

github.com

RuboCop の次のリリース (たぶん 0.59.0) で、ガード条件の後ろに空行を入れる cop がデフォルトで有効ということになる。

auto-correct でガード条件後に空白を適用した例として以下のような diff になる。

 return if guard_condition
+
 do_something

基本的に auto-correct したコードは空行が入るだけのため git blame が汚れないのもデフォルトで有効にしようと思った理由のひとつ。

加えてもともとコアチームメンバーが前向きだったことと、ハートビート.rb や同僚から意見を聞きつつ最終的に有効という判断とした。

デフォルトで無効だった間に rails/rails リポジトリで false positive の検出などをして改善しているので、それなりのユースケースは潰していると思うけれどもし何か見つけたら、upstream か RuboCop JP までフィードバックをお願いします。

リファクタリング 第2版が素晴らしい

同僚の haru01リツイートで『リファクタリング 第2版』のカットオフを読めると知って、Safari online books service で斜め読みした。同サービスへのフリートライアルでも読むことができる。

端的にいうと全面改訂された一冊。結論からいうと発売されたらこれは間違いなく買い。

リファクタリングの題材となるコードが Java から JavaScript になるというという前情報はあったが、実際に見るのとイメージはずいぶん違ったものだった。リファクタリング名について、第一版で Extract Method や Inline Method と名づいていたものは Extract Function や Inline Function といった JavaScript っぽい名前になり、コードも現代の JavaScript ならではのリファクタリングされたクリーンなコードが示されている (細かいことを挙げるとリファクタリングのイメージも UML から模式図に変わっているようだ) 。Martin Fowler がなぜ JavaScript を選んだのか?ということがわかる。第一版を読んでいる世代でも Martin Fowler の示す現代的なクリーンな JavaScript の書き方、書き直し方を知る意味でも価値があるだろう。

また、第一版ではサンプルコードの題材がレンタルビデオであったが、2010 年代も終わりに近い現代にレンタルビデオを使っても読者によっては "What’s a video rental store?" である。ということでサンプルコードのお題が時代背景に依存しないものに変えられている。

第一版から第二版で全面改訂されたというと Kent Beck が記した『エクストリームプログラミング (白本) 』が記憶に強いが、彼と『XP 緑本』を記した Martin Fowler が自身の名著を古典ではなく名著たるを示すため全面改訂を行なっていることに期待が上がる一方だ。

XPエクストリーム・プログラミング実行計画 (The XP Series)

XPエクストリーム・プログラミング実行計画 (The XP Series)

  • 作者: ケントベック,マーチンファウラー,Kent Beck,Martin Fowler,長瀬嘉秀,飯塚麻理香
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2001/04
  • メディア: 単行本
  • 購入: 2人 クリック: 14回
  • この商品を含むブログ (15件) を見る

優れた技術書がとある分野だとその書籍が古典として後に続く名著が現れず、時代による学習接点の断絶が起きることがあるが、現代に合わせた改訂で時代を越えて甦るのは素晴らしいのひとことに尽きると思う。

Refactoring: Improving the Design of Existing Code (2nd Edition) (Addison-Wesley Signature Series (Fowler))

Refactoring: Improving the Design of Existing Code (2nd Edition) (Addison-Wesley Signature Series (Fowler))

表紙も黒と赤のシグネチャシリーズ装丁になり、手元に置く日が楽しみな一冊である。

RSpec 3.8.0 で Change マッチャーの細かな振る舞いが変わった

RSpec 3.8.0 で RSpec::Matchers::BuiltIn::Change マッチャーによる判定に Object#hash も使われるようになった。

以下の PR での変更となる。

github.com

ピンポイントで示すと以下の Change#changed? メソッドの実装で、変更前に保持している hash 値と変更後の hash 値での判定が加わっている (ソースコードコメントにも記されているとおり) 。

github.com

以下、ニッチなケースの話。

Change マッチャーを使ったテストコード例として、以下の model がテスト対象の自前のクラスのオブジェクトだとする。そしてそれが eql? メソッドだけオーバーライドして、hash メソッドをオーバーライドし忘れているようなケースだと、上記 PR の変更によって期待通りのテスト結果を得ることができなくなる。

expect {
  model.do_something
}.not_to change { model }

RSpec 3.7.0 から RSpec 3.8.0 にアップグレードして上記のようなコードでの結果が思わしくなかった場合は、model のクラスの hash メソッドについてオーバーライドもれがないか見てみると良い。

るりまにも示されているように hash メソッドをオーバーライドする必要があるケースをきちんと押さえておくと良いと思いながら、もしかすると Lint として Cop を用意すると良いかもというアイデアにもなったので備忘を兼ねてメモっておく。

docs.ruby-lang.org

当初 RSpec のバグかと思ってみたら意図のある変更で、使っている側の問題だったという。想定される利用規模に対してレポートもないのでそれもそうだったかという感じではあった。

FactoryBot 0.4.11 での非推奨警告を抑える

FactoryBot 0.4.11 で closed_at 1.day.from_now といった FactoryBot のコードに対して以下のような警告が出るようになった。

DEPRECATION WARNING: Static attributes will be removed in FactoryBot 5.0. Please use dynamic
attributes instead by wrapping the attribute value in a block:

closed_at { 1.day.from_now }

To automatically update from static attributes to dynamic ones,
install rubocop-rspec and run:

rubocop \
  --require rubocop-rspec \
  --only FactoryBot/AttributeDefinedStatically \
  --auto-correct

この警告に記されているとおり、RuboCop RSpec の FactoryBot/AttributeDefinedStatically cop が auto-correct を備えているので、そのとおりのコマンドを叩くと警告を抑制する形に変更できる。

RuboCop RSpec を梱包していて、依存が緩められている OnkCop 0.53.0.1 以降だと以下で良い。

% bundle exec rubocop --only FactoryBot/AttributeDefinedStatically -a

余談だけれど、この FactoryBot の警告へ対策として FactoryBot/AttributeDefinedStatically cop の提案と実装をしたダニエルが FactoryBot のコミッターになってリリースされたのがこの 0.4.11 ということで、おめでたい話だった。

github.com