Ginza.rb 第79回

Ginza.rb 第79回 Rails6の新しい定数自動読み込みZeitwerkのコードを読もう!に参加した。会場はメドピアさん。

ginzarb.doorkeeper.jp

表題のとおり今回は Zeitwerk がテーマ。余談だが自分は発音できないのでカタカナ読みでツァイトヴェルクと読んでいたが、それでも読みづらいので Rails コミュニティで略称として使われている zloader (ゼットローダー) の方で読んでいたりする。

オートローダーとは Railsrequire を書かなくてもクラスが使える機構を支えているものだが、Ruby 標準の autoload を Rails が拡張した autoload が Rails 5.2 以前に択一だったもので、Rails 6 で追加されたオートローダーが Zeitwerk となる。従来のオートローダーは classic というもので Active Support が提供している。なお、Rails では Active Support が Zeitwerk に依存してる

autoload はクラスが見つからなかったときにファイルをロードするが、Zeitwerk はその逆でファイル名をもとにクラスをロードする。なのでファイル名とクラス名のマッピングが不確かだと NameError が起きるのでそのあたりはひとつの注意点としましょうとなっている。例としては html_parser.rb は HtmlParserマッピングされるため HTMLParser としたい場合は infrection を使ったマッピングを行う。

github.com

また Zeitwerk はスレッドセーフな実装になっているので、autoload を使っていたときにレースコンディションでエラーになるようなケースが解消されるなどのメリットがあるとのこと。

実装として面白かったのはクラスの reload だが、自分だったら愚直に load メソッド (require と異なり同じファイルを読み直す) を使うのが第一感となるが、require 済みのファイルパスを保持する $LOADED_FEATURES から対象のパスを reject! で破壊的に除いて 再び setup を実行するとかマジかと思って面白かった。このコードは面白かった。印象的なことだったので2度言った。

あと TracePoint が実装として使われていたりもするライブラリなので、TracePoint ファンの人は読んでみると面白いと思う。

今回 willnet さんの主導で README を読んで実装のコード解説に入っていたけれど、時間内にしゅっと本筋のコードを眺めてどういったものかを解説する様はまさに匠の技だった。Zeitwerk への理解が深まりました。ありがとうございました。