ククログ

株式会社クリアコード > ククログ > Ruby 3.4.0のcsv/fiddle/rexml/stringio/strscan/test-unit

Ruby 3.4.0のcsv/fiddle/rexml/stringio/strscan/test-unit

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の変更点はこんな感じです。

GH-296

3つの条件が重なったときにパースに失敗する「ことがある」問題を修正しました。(4つの条件とか言ったほうがいいかもしれないけど、もう1つの条件を説明するのが面倒。。。)

GH-301

CSV.openがデフォルトでBOMを自動検出するようになりました。ただし!Windowsでは自動検出しません。これはRuby本体のWindowsでのBOMの検出機能がなんか変だからです。気が向いたら直そうかと思っていましたが、普段Windowsを使っていないこともあり全然気が向かなかったのでなにもしていません。だれか直して。

なお、CSVにBOMが入る原因のほぼすべてはExcelなはずです。Excelが出力するCSVにはBOMが入っているはずなんです。なので、Windowsでこそこの機能があった方が便利になるはずなのですが、前述の通り無効になっています。Excelで作られたCSVを違う環境で扱うときはこれで便利になるはずです。

GH-300

CSV.openStringIOを受け付けるようになりました。普通は文字列かIOを渡すと思うので、StringIOを受け付ける必要性はあまりないと思うのですが、IOを受け付けるならStringIOも受け付けていいよねーということで受け付けるようになりました。

GH-313

いくつか組み込みで値を変換する機能(たとえば、"1"1にする機能)があるのですが、時刻へ変換する機能が増えました。日付と日付+時刻(datetimeって日本語でなんて言うの?)へ変換する機能は前からあったので、時刻を変換する機能もあっていいよねということです。

GH-319

CSV::TSVクラスが増えました。CSVクラスと同じように使えるのですが、デフォルト設定がTSV(tab-separated values)用になっています。つまり、カラムの区切りがタブになっています。

CSV.open("xxx.tsv", col_sep: "\t")じゃなくてCSV::TSV.open("xxx.tsv")と書けるようになったということです。

GH-311 GH-312

ちょっと速くなりました。

fiddle

fiddle gemは拡張ライブラリーを書かなくてもCで書かれた機能を呼び出せるようにするgemです。fiddle gemの変更点はこんな感じです。

GH-147

JRubyのFiddle実装を取り込みました。今後、Fiddleがdefault gemからbundled gemになるということを見越しての変更です。なお、strscanも同じように数年前にJRuby実装を取り込んでいます。

JRubyにはffi gemの実装が組み込まれているのですが、それの上にFiddleのAPIを実装しています。

GH-149

いろいろすったもんだありましたが、TruffleRubyのFiddle実装も取り込みました。といっても、既存のTruffleRuby内にあるFiddle実装を取り込んだのではなく、既存のTruffleRuby実装を捨てて、JRuby実装をTruffleRubyでも使えるようにしました。TruffleRubyにもffi gemの実装が組み込まれているので、同じ実装を使い回せました。

GH-139

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側を改良して対応しました。

後者は@tompngGH-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の変更点はこんな感じです。

GH-72

REXMLの高速化はstrscanを使うようにしたことによるものが大きいのですが、@naitohはstrscanの改善も合わせて進めています。これはREXMLを高速にするためにStringScanner#capturesのAPIを変更しています。

@naitohによる改良は他にもありますが省略します。

GH-113

整数値に特化した解析メソッド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関連のバグのときに便利です。

GH-237 GH-262

Ruby 3.4向けの変更が入っています。Ruby 3系は高い互換性を維持したまま開発が進んでいますが、ちょいちょい非互換があります。そういうやつにはすでに対応してあるので、Ruby 3.4でもいい感じに動きます。

GH-253

--report-slow-testsオプションを追加しました。遅いテストを遅い順に表示してくれます。この順に高速化していけば効率よくテスト実行時間を高速化できます。

GH-235

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はその問題が直った状態にできます。