Learn Ruby - Modern Ruby 4.0 Features & Upgrade Path
Series/Learn Ruby/Episode 21
Episode 21 of 23

Learn Ruby - Modern Ruby 4.0 Features & Upgrade Path

This episode breaks down Ruby 4.0 features: ZJIT as the next-generation JIT, Ruby::Box for isolated namespaces, Ractor::Port as the ractor communication API, language and library changes, and the upgrade path from 3.4 to 4.0 via deprecation warnings and compatibility testing.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Ruby 4.0 was released on December 25, 2025, right on Ruby's 30th anniversary. Episode 21 breaks down its major features: ZJIT as the next-generation JIT, Ruby::Box for isolated namespaces, Ractor::Port as the new ractor communication API, and various language and standard library changes.

At the end of the episode, we lay out the upgrade path from 3.4 to 4.0 — from deprecation warnings and magic comments to gem compatibility tests. Understanding these updates prepares you to use the current ecosystem.

ZJIT and Ruby::Box

ZJIT

ZJIT is the next-generation Just-in-Time compiler that will serve as the basis for Ruby 4.1 performance. It's still experimental in 4.0 — YJIT remains the recommendation for production. You can try it with a flag when running:

Mengaktifkan ZJIT
ruby --zjit app.rb
ruby --yjit app.rb

ruby --zjit app.rb turns on ZJIT, while ruby --yjit app.rb turns on YJIT. For production, stick with YJIT until ZJIT matures. In the 4.0 release, the previously experimental RJIT was removed — JIT development focus now lies with YJIT and ZJIT.

Ruby::Box

Ruby::Box is an experimental isolated namespace: it lets several versions of a library load in a single process without constant conflicts. Enable it with an environment variable when running Ruby:

Mengaktifkan Ruby::Box
RUBY_BOX=1 ruby app.rb

RUBY_BOX=1 ruby app.rb enables this feature. Isolated namespaces are useful for running plugins or gems whose class definitions clash. Since it's still experimental, test carefully before using it in production.

Language and Library Changes in 4.0

Ractor::Port

The Ractor communication API has been updated. Ractor::Port replaces Ractor.yield and Ractor.take as the communication channel between ractors. Send and receive data through a port:

RubyKomunikasi lewat Ractor::Port
ractor = Ractor.new do
  port = Ractor::Port.new
  Ractor.current[:port] = port
  loop { port.send(port.receive * 2) }
end
 
port = ractor[:port]
port.send(21)
puts port.receive

Ractor::Port.new creates a communication channel, port.send(...) sends, port.receive receives. Ractor#join and Ractor#value remain available for waiting on and fetching results. This new API makes Ractor parallelism more explicit and easier to understand.

Set, Pathname, and Frozen String

Ruby 4.0 makes Set and Pathname core classes — no extra require needed to use them. Frozen string literals are enforced more strongly, and logical operators may now sit at the start of a continuation line:

RubySet core dan operator di awal baris
set = Set[1, 2, 3]
path = Pathname.new("/etc/hosts")
 
hasil = true
  && set.include?(2)

Set[1, 2, 3] is now available out of the box. && at the start of a line keeps long condition chains readable. Ruby 4.0 also supports Unicode 17.0 and allows *nil — multiplying an array by nil yields an empty array.

Upgrade Path from 3.4 to 4.0

Deprecation Warnings

Before migrating, turn on all warnings to see what is deprecated. Running with the -w flag surfaces deprecation warnings in your app and its gems:

Mendeteksi deprecation warnings
ruby -w app.rb

ruby -w app.rb turns on the verbose warning level. Note every deprecation warning in your own code — fix the ones in your application first, then evaluate warnings from gems that are already outdated. These warnings are the roadmap of what must be replaced before 4.0.

Migration and Compatibility Testing

Once the warnings are clean, upgrade gradually by pinning the version in the Gemfile:

Upgrade ke Ruby 4.0
rbenv install 4.0.6
rbenv local 4.0.6
bundle install
bundle exec rspec

rbenv install 4.0.6 installs the latest version, rbenv local 4.0.6 pins the version in the project. After bundle install, run the entire test suite with bundle exec rspec — test failures signal gem compatibility issues that need to be updated or replaced. Check the release notes in NEWS.md and the news page at ruby-lang.org.

Warning

Don't upgrade straight to production. Prepare a branch, fix deprecation warnings first, then validate with the full test suite and staging before promoting.

Conclusion

Key takeaways:

  • ZJIT is the experimental next-generation JIT; YJIT remains the choice for production.
  • Ruby::Box provides an isolated namespace via RUBY_BOX=1.
  • Ractor::Port replaces Ractor.yield and Ractor.take.
  • Set and Pathname are now core classes without an extra require.
  • ruby -w reveals deprecation warnings that should be cleaned up first.
  • Upgrade gradually through a version manager, then validate with the test suite.

In episode 22, the final episode of the series, we look at the modern ecosystem as a whole: Rails 8.x, Sinatra, and Hanami, Rake and Foreman tooling, the alternative implementations JRuby and TruffleRuby, a comparison of Ruby with other languages, plus a recap and a production checklist.

Learn Ruby - Modern Ruby 4.0 Features & Upgrade Path | Learn Ruby