What is New in Ruby 3.4
Ruby 3.4 introduces several enhancements focused on performance, new language features, and updates to the standard library. It also includes some compatibility changes and switches to a new default parser. Below is a detailed overview of the key updates.
Performance Improvements
The YJIT compiler has received major upgrades, resulting in better speed on most benchmarks for both x86-64 and arm64 architectures. Memory usage is lower thanks to compressed metadata and a new unified memory limit.
New options and features for YJIT include:
- A unified memory limit set with
--yjit-mem-size(default is 128 MiB). - Compilation logging enabled via
--yjit-log. - Runtime access to the log through
RubyVM::YJIT.log. - Expanded statistics in
RubyVM::YJIT.runtime_stats, now always available, covering invalidation, inlining, and metadata.
Other optimizations cover:
- Reduced memory for metadata via compressed context.
- Register allocation for local variables and method arguments.
- Rewriting core methods like
Array#each,Array#select, andArray#mapin Ruby when YJIT is active. - Inlining of simple methods (empty, constant-returning, self-returning, or direct argument return).
- Specialized code for more runtime calls.
- Faster string operations such as
String#getbyteandString#setbyte. - Optimized bitwise operations.
- Support for shareable constants in multi-ractor environments.
- JSON parsing is now about 1.5 times faster.
New Language Features
- Block parameters can now use
itto refer to the single argument in simple blocks, making code cleaner.
ary = ["foo", "bar", "baz"]
p ary.map { it.upcase }
# => ["FOO", "BAR", "BAZ"]
**nil is allowed and behaves the same as **{}, passing no keywords without triggering conversions.::Ruby is now reserved; defining it will show a deprecation warning if enabled.Standard Library Updates
Socket: The Socket library now supports Happy Eyeballs Version 2 for faster and more reliable connections, especially with IPv6. It resolves addresses concurrently and attempts connections with IPv6 priority.
Modular GC: Garbage collection can now load alternative implementations dynamically. An experimental MMTk-based GC is available if built with the right options.
GC Configuration: Use GC.config to adjust settings, including a new option to limit full marking.
Ractor Enhancements:
requirenow handles features on the main Ractor.- New methods:
Ractor.main?,Ractor[]andRactor[]=for local storage, andRactor.store_if_absentfor safe initialization.
Tempfile: Tempfile.create(anonymous: true) creates a file that is immediately unlinked.
RubyGems and Bundler: New options for attestations and lockfile checksums.
Several bundled gems have been promoted to newer versions, including bigdecimal 3.1.8, csv 3.3.2, and others.
Compatibility Changes
Language and Core:
- Mutating string literals without
frozen_string_literalnow warns by default in some cases. - Passing blocks or keyword arguments to
[]is no longer supported. - Error messages use single quotes instead of backticks, and class names appear before method names in backtraces.
Hash#inspectuses modern syntax for symbol keys and adds spaces around=>.FloatandString#to_fhandle more decimal formats.Refinement#refined_classhas been removed.
Standard Library:
- Some deprecated parts of DidYouMean, Net::HTTP, Timeout, and URI have been removed or changed.
- win32/sspi.rb moved to an external gem.
C API: Certain deprecated functions and macros are removed.
Other Notable Changes
- Prism is now the default parser instead of parse.y.
- Unused blocks passed to methods trigger warnings in verbose mode.
- Redefining optimized core methods shows performance warnings.
Range#sizeraises an error for non-iterable ranges.- Backtrace handling for exceptions supports
Thread::Backtrace::Locationobjects.