← 記事

IronRuby 4.0.5:.NET 10と.NET 11で動くRuby 4.0

9月末に、prismをパーサーに使ってIronRubyをRuby 4.0に対応させた私のフォーク、IronRuby 4.0について書きました。当時は.NET 8で動き、最初のダウンロードは4.0.0-preview1という名前でした。それから6週間で6つのリリースを重ね、IronRuby 4.0.5が出ました。.NET 10と.NET 11 で動く最初のリリースで、.NET 8を使わない最初のリリースでもあります。

$ ./ironruby -e 'puts RUBY_DESCRIPTION'
IronRuby 4.0.5 (4.0.0) on .NET 10.0.15 [x86_64-linux]

.NET 8をやめた理由

Microsoftによる.NET 8のサポートは、昨日2026年11月10日に終了しました。4.0.4が.NET 8向けの最後のリリースです。4.0.5からIronRubyは net10.0 と net11.0 向けにビルドされ、.NET 8のためだけに必要だったコードは削除されました。

ダウンロードはそれぞれ2種類になりました。

どちらも自分のランタイムを同梱しているので、Rubyスクリプトを動かすだけなら.NETをインストールする必要はありません。IronRubyを組み込むプログラムや、そのアセンブリを読み込むプログラムだけが、.NET 10以降を必要とします。

.NET 11では起動が約5%短くなり、TruffleRubyのベンチマーク集は約3.5%速く動きます。それでも標準を.NET 10にしているのは、LTSリリースだからです。

ランタイムの変更にともなって、小さな変化が2つあります。.NET 9以降の BigInteger の上限により、Integerは約2**31ビットより大きくできなくなりました。1 << 2**31 は、メモリ確保に失敗したときのCRubyと同じく NoMemoryError になります。また、Windowsの zlib は.NETに含まれるzlib-ngを使うようになりました。そのため Zlib::ZLIB_VERSION が変わり、圧縮したバイト列が4.0.4と異なることがあります。展開した結果は同じです。

9月からの変化

4.0.5そのものは小さなリリースです。大きな変更は、その前の4つのリリースにありました。私が特に大事だと思うものを紹介します。

SQLiteを使ったRails、Windowsでも

Sam Ruby(@rubys)さんが、自身のプロジェクトRoundhouseでトランスパイルしたRailsアプリを動かし、最初のバグを見つけてくれました。macOSのパイプとソケットでPumaが起動できなかったこと、大きなレスポンスが途中で切れていた IO#write_nonblock、そしてLinuxでのSQLiteのクラッシュです。3つとも4.0.1で直りました。

4.0.2では、Rails 8.1のアプリがWindows上でSQLiteを使って動きます。gem install rails、rails new、scaffold、マイグレーション、TurboとStimulus、そしてPuma上の bin/rails server までです。Windowsで人気のgemを試したところ、rubocop、rspec、pry、prawnなど81個がCRubyとバイト単位で同じ出力を返しました。TLSもnet/httpとPumaの両方で動きます。

Windowsインストーラーとirb

4.0.3から、RubyInstallerのようなWindowsインストーラーがあります。C:\IronRuby40-x64 にインストールされ、管理者権限は不要で、ironruby、iirb、igem をPATHに追加します。irb と gem はCRubyのままなので、両方を並べて使えます。

irbはWindowsでもCRubyと同じように動くようになりました。色付き表示、型に基づく補完、コンソールでの日本語などの正しい表示に対応しています。また、JRubyのインタプリタが jruby であるように、インタプリタの名前は ironruby になりました。ターミナルでスクリプトなしに起動するとirbが開きます。

Ruby 4らしい書き方で.NETを呼ぶ

.NETの呼び出しがずっと使いやすくなりました。キーワード引数は名前で.NETのパラメーターに結びつき、ブロックはデリゲート型のパラメーターに渡されます。list.Sort { |a, b| b <=> a } や Task.Run { } がそのまま動きます。

@sholdenさんのおかげで、using はC#の using ディレクティブのように.NETの名前空間も受け取れるようになりました。その拡張メソッドは、ファイルの残りの部分だけで有効です。

using System::Linq
list = System::Collections::Generic::List[Integer].new([3, 1, 2])
p list.where { it > 1 }.order_by { -it }.to_a   # => [3, 2]

LINQの101のサンプルはCIで動いています。

ずっと速く

4.0.4は主に速度のためのリリースでした。ベンチマークで洗い出した、IronRubyがCRubyに大きく遅れていた箇所の多くが、解消されたか大きく縮まりました。

弱点は今も例外です。.NETの例外処理の仕組みのため、例外を投げるのに数十マイクロ秒かかり、CRubyの1〜6マイクロ秒に比べて遅いままです。

CRubyにより近く

IronRubyがCRuby 4.0と同じように動くようになった点を、ほかにもいくつか挙げます。

ありがとう

IronRubyは、外部から初めてコントリビューションを受けました。macOSとソケットの修正をしてくれたSam Rubyさん、macOSの File#flock と ir -S を直してくれた@khasinskiさん、そしてrefinement、LINQ、スレッドなど多くを手がけてくれた@sholdenさんに感謝します。

試してみる

リリースページに、Linux x64、Windows x64、Apple silicon搭載macOS向けのダウンロードがあります。Windowsではインストーラー ironruby-4.0.5-win-x64-setup.exe がいちばん簡単です。それ以外ではアーカイブを展開します。

$ tar xzf ironruby-4.0.5-linux-x64.tar.gz
$ cd ironruby-4.0.5-linux-x64
$ ./ironruby
$ ./ironruby script.rb
$ ./igem.sh install rack

どのファイルにも署名付きのビルド来歴証明(attestation)があり、どのワークフローがどのコミットからビルドしたかを確認できます。

$ gh attestation verify ironruby-4.0.5-linux-x64.tar.gz --repo Largo/ironruby

macOS版はCIでビルドしていますが、まだほとんどテストしていません。IronRubyを試して何か動かないことがあれば、issueを作るか、メールをください。

リンク