Rubyの開発に参加している須藤です。そろそろRuby 3.4.0がリリースされるので私がメンテナンスしているdefault gem/bundled gemの変更点を簡単に紹介します。
対象gem
紹介するgemは次の通りです。default gemがRubyに組み込まれているgemで、bundled gemがRubyをインストールするときに普通のgemとしてついでにインストールされるgemです。どちらも新しいバージョンを普通のgemとしてインストールすることで、Ruby本体のバージョンを上げなくても新しいバージョンのgemを使えるようになります。
- csv: bundled gem
- fiddle: default gem
- rexml: bundled gem
- stringio: default gem
- strscan: default gem
- test-unit: bundled gem
csv
csv gemはCSVを扱うgemです。csv gemの変更点はこんな感じです。
3つの条件が重なったときにパースに失敗する「ことがある」問題を修正しました。(4つの条件とか言ったほうがいいかもしれないけど、もう1つの条件を説明するのが面倒。。。)
CSV.open
がデフォルトでBOMを自動検出するようになりました。ただし!Windowsでは自動検出しません。これはRuby本体のWindowsでのBOMの検出機能がなんか変だからです。気が向いたら直そうかと思っていましたが、普段Windowsを使っていないこともあり全然気が向かなかったのでなにもしていません。だれか直して。
なお、CSVにBOMが入る原因のほぼすべてはExcelなはずです。Excelが出力するCSVにはBOMが入っているはずなんです。なので、Windowsでこそこの機能があった方が便利になるはずなのですが、前述の通り無効になっています。Excelで作られたCSVを違う環境で扱うときはこれで便利になるはずです。
CSV.open
がStringIO
を受け付けるようになりました。普通は文字列かIO
を渡すと思うので、StringIO
を受け付ける必要性はあまりないと思うのですが、IO
を受け付けるならStringIO
も受け付けていいよねーということで受け付けるようになりました。
いくつか組み込みで値を変換する機能(たとえば、"1"
を1
にする機能)があるのですが、時刻へ変換する機能が増えました。日付と日付+時刻(datetime
って日本語でなんて言うの?)へ変換する機能は前からあったので、時刻を変換する機能もあっていいよねということです。
CSV::TSV
クラスが増えました。CSV
クラスと同じように使えるのですが、デフォルト設定がTSV(tab-separated values)用になっています。つまり、カラムの区切りがタブになっています。
CSV.open("xxx.tsv", col_sep: "\t")
じゃなくてCSV::TSV.open("xxx.tsv")
と書けるようになったということです。
ちょっと速くなりました。
fiddle
fiddle gemは拡張ライブラリーを書かなくてもCで書かれた機能を呼び出せるようにするgemです。fiddle gemの変更点はこんな感じです。
JRubyのFiddle実装を取り込みました。今後、Fiddleがdefault gemからbundled gemになるということを見越しての変更です。なお、strscanも同じように数年前にJRuby実装を取り込んでいます。
JRubyにはffi gemの実装が組み込まれているのですが、それの上にFiddleのAPIを実装しています。
いろいろすったもんだありましたが、TruffleRubyのFiddle実装も取り込みました。といっても、既存のTruffleRuby内にあるFiddle実装を取り込んだのではなく、既存のTruffleRuby実装を捨てて、JRuby実装をTruffleRubyでも使えるようにしました。TruffleRubyにもffi gemの実装が組み込まれているので、同じ実装を使い回せました。
Ractorに対応しました。
本当は構造体サポート(GH-114)も入れたかったのですが、間に合いませんでした。。。だれか実装したい?
rexml
rexml gemはピュアRubyのXMLパーサーです。rexml gemの変更点はこんな感じです。
大きな変更の1つ目はやはり@naitohによる高速化もろもろですね!#RubyKaigi 2024 LTで「Improved REXML XML parsing performance using StringScanner」というタイトルで発表しました。も見てね。これを機にメンテナーにもなってもらいました。(GH-225)
大きな変更の2つ目はたくさんの脆弱性の対応ですね。。。原因は大きく2つありました。REXMLは正規表現を多用しているのですが、それに起因するReDoSが1つ。大きなXMLをできるだけ少ないリソースで処理できるようにするためのストリーム処理に起因するDoSがもう1つです。
前者は@makenowjustがRuby 3.2以降に入れた改善で発生しなくなっているのですが、Ruby 3.1はまだEOLになっていないので、Ruby 3.1用にREXML側を改良して対応しました。
後者は@tompngがGH-186で抜本的な対策を入れてくれて直りました。なお、@tompngはRubyコミッターになる予定です。(Misc #20946)
他にもいろいろあるのですが、今年はこの2つが大きすぎました。
stringio
stringio gemは文字列をIO
っぽくつかえるようにするためのgemです。stringio gemの変更点はこんな感じです。
JRuby実装がよりいい感じになりました。JRuby実装がstringio gemに取り込まれてからCRuby用実装と同じテストを使うようになったのですが、いくつかのテストは省略していました。そういうのがちょっとずつ減っていっています。
CRuby実装はちょろちょろっとした改良が入っています。
strscan
strscan gemは文字列を高速に解析するためのgemです。strscan gemの変更点はこんな感じです。
REXMLの高速化はstrscanを使うようにしたことによるものが大きいのですが、@naitohはstrscanの改善も合わせて進めています。これはREXMLを高速にするためにStringScanner#captures
のAPIを変更しています。
@naitohによる改良は他にもありますが省略します。
整数値に特化した解析メソッドStringScanner#scan_integer
を追加しました。scanner.scan(/[+-]\d+/).to_i
とかでも整数値を解析できましたが、それより速いです。
strscan gemもJRuby実装を取り込んでいるので、JRubyでもこれらの改良を使えます。しかし、TruffleRuby実装は取り込んでいないので、TruffleRubyではこれらの改良は使えません。TruffleRubyでもstrscan gemをインストールできますが、なにもしないgemになっています。私は、それはユーザーがうれしくないんじゃないかと思うので話はしてみたのですが、そっちの方がTruffleRuby的にはうれしいということで今の形になっています。
test-unit
test-unit gemは単体テスト用のgemです。test-unit gemの変更点はこんな感じです。
--gc-stress
オプションを追加しました。テスト実行中のみGC.stress
を有効にします。GC関連のバグのときに便利です。
Ruby 3.4向けの変更が入っています。Ruby 3系は高い互換性を維持したまま開発が進んでいますが、ちょいちょい非互換があります。そういうやつにはすでに対応してあるので、Ruby 3.4でもいい感じに動きます。
--report-slow-tests
オプションを追加しました。遅いテストを遅い順に表示してくれます。この順に高速化していけば効率よくテスト実行時間を高速化できます。
Thread
を使った並列実行をサポートしました。詳細はtest-unitで並列テスト実行を参照してください。
おまけ:rdoc
RDocはメンテンナンスしていませんが、Ruby 3.4.0に組み込まれるRDocにはRed Data Tools:RDocとRubyGemsを疎結合にしたい!が入っていることをアピールしておきます。
まとめ
そろそろRuby 3.4.0がリリースされているので、私がメンテナンスしているdefault gem/bundled gemの変更点を紹介しました。普通のgemとしてもリリースしてあります。つまり、今でも試せる状態になっています。もし、なにか問題を見つけたら教えてください。3.4.0リリース前に直せれば3.4.0に組み込まれるgemはその問題が直った状態にできます。