今週は以下のようなことを話していた
PRIsVALUE
とは何?
最後の PRIsVALUE
とかはビルドエラーなどでよく見るマクロだったので、どういう意味なのか、ということを akr さんなどに解説してもらってとても勉強になった。ありがたい。
extensions
ディレクトリを参照する昨年 gem-ext-cleaner の時に軽く触れた話なのだけど、 RubyGems 3.4 では ext
配下はインストール後に make clean
されるようになっている。つまり、ext
の下に .so
などがあるのを期待しているコードは動かなくなるので、以下のような対応をあちこちで必要となっていた。
僕の方でめぼしい gem については全部直したのだけど、あるから使うというのは良くない文化に思う。そういう話でRubyGems は伝統的に lib
の下に lib/foo.so
というようにコピーしているので、それを使っていたり、nokogiri のように lib/3.3/
というディレクトリを掘った上で .so などを配布しているのだけど、これらは全部間違いで、gem のインストールディレクトリの extensions
フォルダの下にある .so を使うのが正解。
このフォルダはハードコードじゃなくても以下のようなコードで取得できるし、gem の activate の段階で勝手に $LOAD_PATH
に追加される。
>> Gem.loaded_specs["date"].extension_dir
=> "/Users/hsbt/.local/share/gem/extensions/arm64-darwin-23/3.4.0+0-static/date-3.3.4"
見ての通り、アーキテクチャや Ruby のバージョンも含まれているので、これを参照する限りは OS のアーキテクチャが変わったとか、Ruby のバージョンが変わったという外部の変更にも耐えることができる。自分は複数の Ruby バージョンや amd64 と arm64 を具ちゃ混ぜにして使っても別に問題ない、という日々なのでこれを標準にしたいのだけど、どうやっていくかなあ、ということで、まずは lib
の下にコピーするという機能を無効にできるようにしてみた。
gem-ext-cleaner を使い始めてから半年くらいにわたって lib
の下の .so を消して暮らしていても何も困ることはないので、別に大丈夫なんじゃないかなあ。.so が2つあるの、エコじゃないのでなんとかしたい。
今週も discord で開催...していたけど、仕事環境の都合でこの日はテキストで軽く眺める程度だった。
https://asakusarb.esa.io/posts/1186
予告に書いた通り、RubyConf AU のフライトの手配と来週の in-person での Asakusa.rb の準備をして終わり。