週刊Railsウォッチ(20200225前編)RubyのShellwordsライブラリは知っておくべき、VCRはやはり有能、copを自作、Hix on Rails記事ほか|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社

RuboCopでコードレビュー支援: Net::HTTPを使わせないcop(Hacklines より)

そういえば以前業務で似たことをやったので、メモがてら置いておきます。

Dir.chdir はスレッドセーフではない

Sidekiq で Dir.chdir を使ったら、他のジョブと干渉してハマりました。

Feature #9785: Feature Proposal: Dir.chdir Thread Safety - Ruby master - Ruby Issue Tracking System

↑ こちらの Issue を見つけるまで、Dir.chdir がスレッドセーフでないことを知りませんでした。Dir.chdir はプロセス全体の working directory を変えてしまうようです。裏側を想像するに仕方がない気はしますが、ruby のドキュメントには書いてないです。

今後レビューで指摘し続けるのも大変なので、RuboCop の custom cop で解決できないか検討しました。

RuboCop の custom cop は作成も導入も割と簡単だった

とは言え、rubocop-rspec みたいな gem を作るのは大げさです。

調べたところ、gem を作らずに、簡単に自作の custom cop を導入することが出来ました。

ruby 付属の ruby-parse コマンドで AST(抽象構文木)を得ることが出来ます。

$ ruby-parse -e 'Dir.chdir'
(send
  (const nil :Dir) :chdir)

$ ruby-parse -e 'hoge ? :aaa : :bbb'
(if
  (send nil :hoge)
  (sym :aaa)
  (sym :bbb))

nil と nil? の微妙な違い、… 等は RuboCop の事情というか構文です。公式マニュアルに書いてあります。
https://github.com/rubocop-hq/rubocop/blob/v0.80.0/manual/node_pattern.md

追記: 2024-11-17

現在は rubocop-thread_safety gem に組み込まれているようです。Gist のコメント で教えてもらいました。

https://github.com/rubocop/rubocop-thread_safety/blob/v0.6.0/docs/modules/ROOT/pages/cops_threadsafety.adoc#threadsafetydirchdir