Ruby 3.3
Summary
Ruby 3.3 is the latest stable version of Ruby. Many new features and improvements are included for the increasingly diverse and expanding demands for Ruby. With this major update from Ruby 3.2 in Fedora 39 to Ruby 3.3 in Fedora 40, Fedora becomes the superior Ruby development platform.
Owner
- Name: Vít Ondruch
- Email: vondruch@redhat.com
- Name: Mamoru Tasaka
- Email: mtasaka@fedoraproject.org
Current status
- Targeted release: Fedora Linux 40
- Last updated: 2024-02-28
- Announced
- Discussion thread
- FESCo issue: #3102
- Tracker bug: #2251105
- Release notes tracker: #1079
Detailed Description
Ruby 3.3 is upstream's new major release of Ruby. Ruby 3.3 adds a new parser named Prism, uses Lrama as a parser generator, adds a new pure-Ruby JIT compiler named RJIT, and many performance improvements especially YJIT.
Prism
- Introduced the Prism parser as a default gem
- Prism is a portable, error tolerant, and maintainable recursive descent parser for the Ruby language
- Prism is production ready and actively maintained, you can use it in place of Ripper
- There is extensive documentation on how to use Prism
- Prism is both a C library that will be used internally by CRuby and a Ruby gem that can be used by any tooling which needs to parse Ruby code
- You can now use
ruby --parser=prism
orRUBYOPT="--parser=prism"
to experiment with the Prism compiler. Please note that this flag is for debugging only.
Use Lrama instead of Bison
- Replace Bison with Lrama LALR parser generator
YJIT
- Major performance improvements over 3.2
- Support for splat and rest arguments has been improved.
- Registers are allocated for stack operations of the virtual machine.
- More calls with optional arguments are compiled.
- Unsupported call types no longer exit to the interpreter.
- Basic methods like Rails
#blank?
and specialized#present?
are inlined. Integer#!=
,String#!=
,Kernel#block_given?
,Kernel#is_a?
,Kernel#instance_of?
,Module#===
are specially optimized.- Compilation speed is now slightly faster than Ruby 3.2.
- Now more than 3x faster than the interpreter on Optcarrot!
- Significantly improved memory usage over Ruby 3.2
- Metadata for compiled code uses a lot less memory.
- More compact code is generated on Arm64.
- Code GC is now disabled by default
- Add
RubyVM::YJIT.enable
that can enable YJIT at run-time- You can start YJIT without modifying command-line arguments or environment variables. Rails 7.2 will enable YJIT by default using this method.
- This can also be used to enable YJIT only once your application is done booting.
--yjit-disable
can be used if you want to use other YJIT options while disabling YJIT at boot.
- More YJIT stats are available by default
- Add more profiling capabilities
- More thorough testing and multiple bug fixes
RJIT
- Introduced a pure-Ruby JIT compiler RJIT and replaced MJIT.
- RJIT supports only x86_64 architecture on Unix platforms.
- Unlike MJIT, it doesn’t require a C compiler at runtime.
- RJIT exists only for experimental purposes.
- You should keep using YJIT in production.
M:N thread scheduler
- M:N thread scheduler was introduced.
- M Ruby threads are managed by N native threads (OS threads) so the thread creation and management cost are reduced.
- It can break C-extension compatibility so that M:N thread scheduler is disabled on the main Ractor by default.
RUBY_MAX_CPU=n
environment variable sets maximum number of N (maximum number of native threads). The default value is 8.- Since only one Ruby thread per Ractor can run at the same time, the number of native threads will be used, which is the smaller of the number specified in
RUBY_MAX_CPU
and the number of running Ractors. So that single Ractor applications (most of applications) will only use 1 native thread. - To support blocking operations, more than
N
native threads can be used.
- Since only one Ruby thread per Ractor can run at the same time, the number of native threads will be used, which is the smaller of the number specified in
Performance improvements
defined?(@ivar)
is optimized with Object Shapes.- Name resolution such as Socket.getaddrinfo can now be interrupted (in environments where pthreads are available).
- Several performance improvements to the Garbage Collector
Other notable changes since 3.2
- IRB has received several enhancements, including but not limited to:
- Advanced
irb:rdbg
integration that provides an equivalent debugging experience topry-byebug
. - Pager support for
ls
,show_source
andshow_cmds
commands. - More accurate and helpful information provided by the
ls
andshow_source
commands. - Experimental autocompletion using type analysis
- Advanced
- ext/readline is retired
- Replaced by
reline
that is pure Ruby implementation compatible withext/readline
API.
- Replaced by
- RubyGems and Bundler warn if users require gem that is scheduled to become the bundled gems in the future version of Ruby.
Feedback
Benefit to Fedora
With a latest release, Ruby language is supporting the newest language features, which enables even faster and easier development of Ruby applications.
Scope
- Proposal owners:
- Finish packaging of Ruby 3.3. Current changes available in PR https://src.fedoraproject.org/rpms/ruby/pull-request/159
- Rebuilding of Ruby packages providing native extensions (i.e. packages which depends on libruby).
- Other developers:
- Rebuild of packages with binary extensions (i.e. packages which depends on libruby) will be handled automatically, but some packages might need fixes/updates to support Ruby 3.3 properly.
- Release engineering: #11753
- The packages are going to be rebuild in side-tag, but that does not need releng involvement nowadays.
- Policies and guidelines: N/A (not needed for this Change)
- Trademark approval: N/A (not needed for this Change)
- Alignment with Community Initiatives:
Upgrade/compatibility impact
- User specific Ruby binary extensions need to be rebuild.
- Ruby packages/application dependencies might need to be adjusted if newly bundled gems are used.
How To Test
- No special hardware is needed.
- To test, install Ruby 3.3. The test builds are published in PR or on Ruby-SIG ML
- Try to locally rebuild your packages using Ruby 3.3.
- Use the packages with your applications previously written in Ruby.
- If something doesn't work as it should, let us know.
User Experience
The Ruby programs/scripts should behave as they were used to.
Dependencies
$ dnf repoquery --disablerepo=* --enablerepo=rawhide --enablerepo=rawhide-source --arch=src --whatrequires 'ruby-devel' | sort | uniq | wc -l 134
Contingency Plan
- Contingency mechanism: We would like to get a special buildroot tag to be able to rebuild necessary the packages with Ruby 3.3. If anything goes wrong, the tag could be easily dropped and previous version of Ruby 3.2 and its dependencies stays intact. The tag would be merged into F40 after everything is rebuild.
- Contingency deadline: Mass Rebuild
- Blocks release? No
Documentation
- Help and documentation for the Ruby programming language
- Ruby 3.3.0 NEWS
- Ruby 3.3.0 release announcement
Release Notes
- The Ruby 3.3 bumps soname, therefore Ruby packages, which use binary extensions, should be rebuilt. Nevertheless, since upstream paid great attention to source compatibility, no changes to your code are needed.