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の挙動変更
*nilがnil.to_aを呼ばなくなった。nil.to_aをオーバーライドしてる人はほぼいないと思うけど、一応。
Ractor APIが変わった
Ractor.yieldとRactor#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