メドピア開発者ブログ

集合知により医療を再発明しようと邁進しているヘルステックカンパニーのエンジニアブログです。読者に有用な情報発信ができるよう心がけたいので応援のほどよろしくお願いします。

#RubyKaigi 2026 で発表されたRubyのAOT Compiler Spinelで作ったものを自慢しよう!

こんにちは、メドピアのサーバーサイドエンジニアの草分( @Lni_T )です。

RubyKaigi 2026参加者の皆さん、お疲れ様でした。 今回は北海道は函館での開催ということで、名所にグルメに楽しいことが目白押しでしたが、皆さん満喫できましたでしょうか?

草分は函館だけでなく小樽や札幌まで足を伸ばしていました。北海道、また行きたいですね。

海の幸を満喫

Spinel

さて、今回の本題はSpinelです。RubyKaigi最終日、Matzさんのキーノートで発表され、話題となったツールですね。

github.com

SpinelはRubyのAOT Compilerで、Rubyコードをスタンドアロン実行可能なネイティブ実行ファイルにコンパイルすることが可能です。

処理の流れとしては以下のように説明されています。

Ruby ソースコード (.rb)
    ↓
spinel_parse:Prism を使用した解析
    ↓
AST テキストファイル
    ↓
spinel_codegen:型推論および Cコードの生成
    ↓
C ソースコード (.c)
    ↓
cc -O2 -Ilib -lm:標準の Cコンパイラ + ランタイムヘッダー
    ↓
ネイティブバイナリ:スタンドアロン(実行時の依存関係なし)

そう、RubyのインストールなしにRubyコードが動作するようになります。

とはいえ、もちろん制約はあり、evalやメタプログラミングなどはサポートされていない旨がREADMEに記載されています。 「Railsサーバーがそのまま動く!」といったソリューションではないようですね。

作ったものを自慢しよう!のコーナー

それでは、Spinelにはどこまでのパワーがあるのでしょうか? ちょっとひねったものを実装して確かめてみましょう。

1. ○×ゲーム(Tic Tac Toe)

実装

ソースコード

気づき

Ruby版/Spinel版で挙動が変わるケースがある

# array.rb
ary = Array.new(3, nil)
puts ary.inspect

上記のコードは、Rubyで実行した場合とSpinelでコンパイルした場合で結果が異なります。

$ ruby array.rb
[nil, nil, nil]
$ ./array
[0, 0, 0]

nilで初期化した配列ですが、Spinel版では0が出力されます。RubyにはNIlClassがありますが、C言語のnullにそのような概念はないせいか、どうも0として扱われてしまうようです。
この辺りの挙動はC言語に変換されている以上は致し方ない所でしょうか。

※2026/05/19追記: 上記の挙動は修正されました!🙇 最新版をfetchしてmakeしましょう!

適宜、Rubyコードとコンパイル済バイナリの実行結果を比較しつつ実装すると安全に開発できそうですね。

型の制約

Rubyでは型宣言などを書かず、やりたい放題プログラムを実装できますが、 Spinelを利用する場合、少々型の制約を受けてしまうようです。

# apple.rb
ary = Array.new(3)
ary[0] = "apple"
puts ary.inspect

例えば、上記のコードはSpinelではコンパイルエラーになります。

$ ../spinel apple.rb
/tmp/spinel_out.xxxxxx/out.c:23:34: error: incompatible pointer to integer conversion passing 'char *' to parameter of type 'mrb_int' (aka 'long long') [-Wint-conversion]
    sp_IntArray_set(lv_ary, 0LL, (&("\xff" "apple")[1]));
                                 ^~~~~~~~~~~~~~~~~~~~~~

int配列と認識されている配列の値に文字列を代入しようとしたため、エラーになってしまうようですね。

以下のように、型を合わせることでコンパイルを通すことができます。

ary = Array.new(3, "")
ary[0] = "apple"
puts ary.inspect

2. スネークゲーム

実装

ソースコード

気づき

system が使える

Rubyで外部コマンドを実行する Kernel.#system も動作します。

Spinel単体ではsleepが整数秒単位でしか動作しないなどの制限もあり、このデモコードでは外部コマンドに頼っています。
※2026/05/19追記: ↑こちらも修正されました!

しかし、この方法は環境依存要因が増えてしまいますね。せっかくスタンドアロン実行可能形式にコンパイルしたのに、これでは本末転倒かもしれません。

おわりに

ちょっとしたツールを作って運用する場合「Goでビルドする」手段が強力です(最近ならRustも選択肢に)。また、さらに前の時代であれば「Perlでスクリプトを書く」というのも有力で、Rubyでツールを作るケースは少なかったように思います。

こうしたユースケースに対してRubyも参入できるのかも!と思うと、なかなか夢が広がるツールだなぁと感じています。今後の動向が楽しみですね!


是非読者になってください!


メドピアでは一緒に働く仲間を募集しています。
ご応募をお待ちしております!

■募集ポジションはこちら hrmos.co

■エンジニア紹介ページはこちら engineer.medpeer.co.jp

■メドピア公式YouTube  www.youtube.com

■メドピア公式note
style.medpeer.co.jp