Sampo Kuokkanen
Sampo Kuokkanen
Ruby, Rails ·

Rails 8アプリをRuby 4.0にアップグレードした

Ruby 4.0が出た

2025年のクリスマスにRuby 4.0.0がリリースされた。Rubyの30周年。 メジャーバージョンアップなので身構えたけど、実際にやってみたらそこまで大変じゃなかった。

うちのプロダクション環境で動いてるRails 8.1アプリ(Japan Voyage)をRuby 3.4.1から4.0.1にアップグレードした話。

Ruby 4.0で何が変わった?

気になるところだけ。

ZJIT

YJITとは別の新しいJITコンパイラ。メソッドベースのコンパイル方式で、YJITより「教科書的」な設計らしい。まだ実験的。

Frozen String Literals

Ruby 3.4から警告が出てたやつ。# frozen_string_literal: trueのコメントがないファイルで文字列を変更すると警告が出る。4.0でもまだデフォルトでfrozenにはなってないけど、方向性は決まってる。

Setがコアクラスに

require "set"が不要になった。Set#inspectの出力も変わってSet[1, 2, 3]になる。

*nilの挙動変更

*nilnil.to_aを呼ばなくなった。nil.to_aをオーバーライドしてる人はほぼいないと思うけど、一応。

Ractor APIが変わった

Ractor.yieldRactor#takeが廃止。Ractor::Portベースに。Ractor使ってなければ関係ない。

CGIライブラリ削除

cgiが消えた。cgi/escapeだけ残ってる。Railsは内部で対応済み。

実際のアップグレード手順

1. .ruby-versionを書き換える

4.0.1

これだけ。

2. Dockerfileも更新

ARG RUBY_VERSION=4.0.1

3. bundle install

$ bundle install

279個のGemが全部入った。Rails 8.1はRuby 4.0対応済みなので問題なし。

4. テスト

$ bin/rails test test:system

1347テスト、3617アサーション、失敗ゼロ。そのまま通った。

5. CI

GitHub Actionsで.ruby-versionを参照してるなら変更不要。

- name: Set up Ruby
  uses: ruby/setup-ruby@v1
  with:
    ruby-version: .ruby-version
    bundler-cache: true

ハマったところ

macOSでOpenSSLのビルドエラー

rbenv install 4.0.1したらOpenSSLが見つからないと言われた。

OpenSSL library could not be found.

ruby-buildを最新にしてから、PKG_CONFIG_PATHを指定したら通った。

$ brew upgrade ruby-build
$ PKG_CONFIG_PATH="/opt/homebrew/opt/openssl@3/lib/pkgconfig" \
    rbenv install 4.0.1

Dockerビルドでpsychが入らない

Dockerイメージをビルドしたらpsychgemのインストールで落ちた。Ruby 4.0ではpsychをソースからビルドするようになったので、libyaml-devが必要。

Dockerfileのビルドステージに追加したら解決。

apt-get install --no-install-recommends -y build-essential git pkg-config libyaml-dev

frozen_string_literal警告

一部のGemで警告が出る。自分のコードには# frozen_string_literal: trueを付けてたので特に困らなかった。

感想

メジャーバージョンアップの割にあっさり終わった。Ruby 3.4で非推奨警告をちゃんと出してくれてたおかげだと思う。

テストがちゃんとあるプロジェクトなら、まずやってみるのが早い。

Set[1, 2, 3]  # Ruby 4.0のSet