Ginza.rb 第79回 Rails6の新しい定数自動読み込みZeitwerkのコードを読もう!に参加した。会場はメドピアさん。
表題のとおり今回は Zeitwerk がテーマ。余談だが自分は発音できないのでカタカナ読みでツァイトヴェルクと読んでいたが、それでも読みづらいので Rails コミュニティで略称として使われている zloader (ゼットローダー) の方で読んでいたりする。
オートローダーとは Rails で require
を書かなくてもクラスが使える機構を支えているものだが、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 を使ったマッピングを行う。
また Zeitwerk はスレッドセーフな実装になっているので、autoload を使っていたときにレースコンディションでエラーになるようなケースが解消されるなどのメリットがあるとのこと。
実装として面白かったのはクラスの reload だが、自分だったら愚直に load
メソッド (require
と異なり同じファイルを読み直す) を使うのが第一感となるが、require
済みのファイルパスを保持する $LOADED_FEATURES
から対象のパスを reject!
で破壊的に除いて 再び setup を実行するとかマジかと思って面白かった。このコードは面白かった。印象的なことだったので2度言った。
あと TracePoint
が実装として使われていたりもするライブラリなので、TracePoint
ファンの人は読んでみると面白いと思う。
今回 willnet さんの主導で README を読んで実装のコード解説に入っていたけれど、時間内にしゅっと本筋のコードを眺めてどういったものかを解説する様はまさに匠の技だった。Zeitwerk への理解が深まりました。ありがとうございました。