タイトル原文: コード懇親会 @ RubyKaigi 2026 / Ruby x Rust 分科会
コード懇親会 @ RubyKaigi 2026 / Ruby x Rust テーブル
今日のアジェンダ
Rustのメリット — メモリ安全性を中心に
Rustでgemを書く — 開発体験のメリット
bundlerを使ったRust gem作成手順
まとめ
Rustのメモリ安全性のための文法的機能
所有権
借用
ライフタイム
(メモリ安全性のみがメリットでもないとは思うのですが<br>大きなメリットということでこの文脈で紹介します)
具体的には
Rustはコンパイル時に **所有権(ownership)** と **借用(borrow)** をチェック
ダングリングポインタ、use-after-freeなどを **コンパイルエラー** で防止
GCなしでメモリ安全を実現 → パフォーマンスと安全性を両立
C/C++で長年悩まされてきたメモリバグのカテゴリがまるごと消える
dangling pointerとは?
すでに解放・破棄されたメモリ領域を指し続けているポインタのこと
Cでは関数のローカル変数のアドレスを返すだけで簡単に作れてしまう
Cでdangling pointerになる例
`x` は関数を抜けるとスタックから消える
返されたポインタはもう無効 → **未定義動作**
実行例
NOTE: `-w` で警告を消しているが、実際はコンパイラが警告してくれはする
コンパイラが教えてくれる:
→ ライフタイムの仕組みにより、**dangling pointerはそもそも作れない**
補足: ライフタイムとは何か
Rustの参照 `&T` には必ず **ライフタイム(生存期間)** が紐づく
コンパイラは「参照先のデータが、参照より長く生きているか」を検証する
`'a` = 「呼び出し元が期待する生存期間」
`x` は関数を抜けると破棄される → `'a` を満たせない → **コンパイルエラー**
Cにはこの仕組みがないので、プログラマの注意力だけが頼り
参照ではなく値そのものを返す → 所有権がムーブされる
コンパイラがメモリ上の位置をいい感じにする
ムーブの話は次に詳しく
ヒープに明示的に置きたければ `Box<i32>` を使う
use-after-freeとは?
`free()` などで解放済みのメモリに再びアクセスしてしまうこと
解放後もポインタ変数自体は残っているため、コード上は普通にアクセスできてしまう
データ破壊、クラッシュ、任意コード実行など深刻な脆弱性につながる
ブラウザやOSカーネルでも頻繁に報告される
今回は、ASan(AddressSanitizer)に敢えて検出させて確認
ちなみにASan有効はオーバーヘッドがあり、一般に実行時間は x2 程度になるそう
コンパイラが教えてくれる:
→ **解放済みの値は二度と使えない**。コンパイラが保証する
なぜuse-after-freeを防げるのか
`drop(buf)` は `buf` の **所有権をムーブ** している
Rustでは値を関数に渡す = 所有権の移動(ムーブ)
ムーブ後の変数はもう**使えない** — これが所有権システムの基本ルール
`drop()` はよくあるイディオム
`drop()` は特別な関数ではなく、ただ **値を受け取って何もしない** だけとわかる
所有権の仕組みそのものが、use-after-freeを構造的に不可能にしている
まとめ
あるデータ `Type` に対して:
不変参照(`&Type`)は、何個でも作れる(みんなで同時に読める)
可変参照(`&mut T`)は、1つしか作れない(書き込めるのは1人だけ)
不変参照が残っていると可変参照は作れない
可変参照が残っていると不変参照は作れない
Rustでgemを書くメリット
無論、 C と比べた安全性はあるが、他にも色々紹介
型を決めよう
**型から設計できる**
関数のシグネチャを書くだけで設計の骨格ができる
`struct` / `enum` でドメインモデルを明確に表現
Cの `void *` 地獄からの解放
エディタの支援が強力
**rust-analyzer** が型推論・補完・リファクタリングを強力サポート
関数の引数の型、返り値の型をインラインで表示
コンパイルエラーをリアルタイムで表示 → 書いた瞬間に間違いがわかる
Cのext gemでは得られなかった開発体験
clippy などの優れたリンターも簡単に連携可能
Rustのライブラリ・資産を使える
**crates.io** に10万以上のライブラリ
`serde` — 高速なマルチフォーマット対応のシリアライズ/デシリアライズ
`rayon` — お手軽データ並列処理
`tokio` — 非同期ランタイム
`Cargo.toml` に一行追加するだけで使える
Cのように依存ライブラリのビルド設定で苦しまない
ちなみに...
💡 実はCargoの作者の一人は **Yehuda Katz** — bundlerの作者でもある
そりゃ〜使いやすいよね!
Rust gem のプロジェクトを作る
`--ext=rust` を指定するだけでRust拡張のひな形ができる
bundler 2.4+ で対応
**magnus** クレート = RubyのC APIのRustバインディング
`#[magnus::init]` でRuby拡張のエントリポイントを定義
`define_module`, `define_global_function` など直感的なAPIが用意される
もちろん、事前にRustとCargoをインストールしてください!
`rake compile` で Cargo → `.so` / `.bundle` をビルド
あとは普通のgemと同じように使える
いきなり書いてみる?
ドキュメント: https://docs.rs/magnus/latest/magnus/#examples
多分... 補完に任せればなんとなく書けるんじゃないかなあ
まとめ
**Rustはメモリ安全** — dangling pointer、use-after-freeなどなどを **コンパイル時に防止**
**Rustでgemを書く** メリットは大きい
型による設計、エディタ支援、豊富なライブラリ
**bundlerが `--ext=rust` をサポート** — 今すぐ始められる
Rubyの柔軟さ × Rustの安全性・生産性 = 型が決まる = 気持ちいい!
参考リンク
[magnus — RubyのRustバインディング](https://github.com/matsadler/magnus)
[The Rust Programming Language (日本語)](https://doc.rust-jp.rs/book-ja/)
[bundler拡張ガイド](https://bundler.io/guides/creating_gem.html)
[RustでRuby gemを書くガイド (公式)](https://www.rust-lang.org/)
おまけコンテンツ
RustでJSONパーサを書いてみよう: