See all articles
Ruby 3.4.0 Release - What's New and How Does It Impact Your Project?

Ruby 3.4.0 Release - What's New and How Does It Impact Your Project?

Ruby 3.4.0, released on December 25, 2024, introduces several noteworthy features and improvements that enhance the language's usability, performance, and developer experience. It was quickly followed with 3.4.1. release that updated version number in Ruby's code.

Whether you develop your Ruby code in-house, using Ruby development services, or creating a Ruby on Rails web app - let's take a deeper look into language changes and their potential influence on your project.

Table of Contents

Ruby 3.4 Changelog: What's New in Ruby 3.4 and What Changed?

Modular Garbage Collection (GC)

Gains: improved performance, reduced infrastructure costs, enhanced system reliability

Ruby's system for cleaning up unused memory is now more flexible, allowing different methods to be used as needed.

Ruby introduces a modular garbage collection framework, enabling alternative GC implementations to be loaded dynamically. By configuring Ruby with `--with-modular-gc` at build time, developers can specify GC libraries at runtime using the `RUBY_GC_LIBRARY` environment variable. This modularity facilitates experimentation and optimization of memory management strategies. 

This ability also allows for tailoring solutions to specific workloads - e.g., by selecting a proper garbage collector to achieve reduced latency in real-time applications.

With Ruby 3.4.0, an experimental implementation of MMTk has been included, offering developers a plug-and-play approach to testing modern GC techniques. MMTk, or Memory Management Toolkit, is a framework designed for implementing and experimenting with garbage collectors (GCs). Originally created for research purposes, MMTk provides a highly modular and reusable architecture that enables developers to create, test, and deploy garbage collection strategies with minimal effort.

In addition, optimal use of garbage collection minimizes memory leaks and excessive memory usage. This reduces the overall resource footprint of the application and infrastructure costs. Now, projects can operate on smaller infrastructure (e.g., fewer servers or smaller virtual machines), leading to lower hosting and cloud costs.

Prism as the default parser

Gains: better performance and maintainability, error tolerance

Ruby has updated its internal mechanism for understanding code by adopting a new parser, Prism, aiming to improve the language's processing capabilities. Prism aims to process code more efficiently and handle errors better than the parser used as a default in previous versions of Ruby.

The default parser has been switched from parse.y to Prism, introduced in Ruby 3.3 (released in December 2023). Prism was designed to be error-tolerant, portable, maintainable, fast, and efficient, addressing several limitations of the previous parser. 

The introduction of Prism in Ruby 3.3.0 was met with a generally positive reception from the Ruby community. Post-release discussions highlighted the potential of Prism to facilitate the development of new static analysis tools for Ruby, marking a significant advancement for the language. Additionally, the JRuby team immediately integrated Prism support, indicating its adaptability across different Ruby implementations. Moreover, tools like RuboCop considered adopting Prism to stay current with Ruby's evolving syntax, acknowledging the need to manage Prism-specific issues. 

Adopting Prism in Ruby 3.4 as a default parser was a natural progression for the Ruby language. Developers can revert to the traditional parser using the command-line argument `--parser=parse.y` if needed. This change enhances the stability and maintainability of Ruby applications by providing a more robust parsing mechanism.

YJIT enhancements

Gains: performance gains, reduced operational costs, enhanced scalability

Ruby programs can now run faster and use memory more efficiently, leading to better overall performance.

YJIT, Ruby's Just-In-Time compiler, introduced back with the release of Ruby 3.1, has received several significant optimizations. 

Developers praised this new JIT solution for delivering tangible performance gains with minimal effort, making it one of the most impactful additions to Ruby in recent years. Open-source contributors and companies like Shopify invested in improving YJIT, underscoring its potential.

Changes made to YJIT in the newest Ruby 3.4 include:

  • Memory usage
    Introduction of a unified memory limit (`--yjit-mem-size`) to track total YJIT memory usage, replacing the previous `--yjit-exec-mem-size` option.
  • New features
    Addition of `--yjit-log` for enabling a compilation log and `RubyVM::YJIT.log` for runtime access to the compilation log.
  • Optimizations
    Compressed context for reduced metadata storage, register allocation for local variables and method arguments, and inlining of small/trivial methods.

These enhancements collectively contribute to improved performance across most benchmarks on both x86-64 and arm64 platforms. 

Introduction of it as a block parameter reference

Gains: improved collaboration and productivity

Ruby now allows the use of it within blocks to refer to the block's single parameter, making the code more readable and concise.

The `it` keyword serves as an alias for `_1`, enabling developers to reference the first block parameter without explicitly naming it. This is particularly useful in simple, one-line blocks, reducing the need for additional variable declarations.

Happy Eyeballs Version 2 implementation in the socket library

Gains: faster connections, increased performance, stability, and availability

Establishing network connections in Ruby is now faster and more reliable, thanks to improvements that help quickly find the best way to connect to other servers.

The socket library now implements Happy Eyeballs Version 2 (RFC 8305), enhancing connection establishment by concurrently resolving IPv6 and IPv4 addresses and attempting connections in a staggered manner. This approach minimizes delays caused by unresponsive IP addresses, improving the efficiency of methods like TCPSocket.new and Socket.tcp.

With this change, applications establish connections faster, especially in environments where one protocol (e.g., IPv6) might be slower or unavailable. This is critical for customer-facing applications, where speed directly affects user experience.

This change also speeds up operations that rely on network connections, such as API calls, third-party integrations, and external database connections.

Standard Library updates

Gains: improved collaboration and productivity, performance improvement

Ruby's built-in tools have been improved to make development smoother and more efficient.

Notable updates include:

  • RubyGems
    Addition of the `--attestation` option to gem push, enabling storage of signatures to sigstore.dev.
  • Bundler
    Introduction of `lockfile_checksums` configuration to include checksums in fresh lockfiles and `bundle lock --add-checksums` to add checksums to existing lockfiles.
  • JSON
    Performance improvements in `JSON.parse`, making it approximately 1.5 times faster than in json-2.7.x.
  • Tempfile
    Implementation of the anonymous: true keyword argument for `Tempfile.create`, which removes the created temporary file immediately, eliminating the need for manual cleanup.

Compatibility and Syntax Changes

Gains: improved collaboration and productivity

Some error messages and how certain code elements are displayed have been updated to be clearer and more consistent.

Key changes include:

  • Error messages and backtraces
    Now, use single quotes instead of backticks and display a class name before a method name when the class has a permanent name.
  • Hash#inspect rendering
    Symbol keys are displayed using the modern symbol key syntax (e.g., `{user: 1}`), and other keys now have spaces around => (e.g., `{"user" => 1}`).
  • Kernel#Float()
    Now accepts decimal strings with the decimal part omitted (e.g., `Float("1.")` returns `1.0`).
  • String#to_f
    Now accepts decimal strings with the decimal part omitted, with changes in behavior when an exponent is specified (e.g., `"1.E-1".to_f` now returns `0.1`).

These updates aim to enhance code readability and consistency, aligning with modern Ruby practices.

In summary, Ruby 3.4.0 brings significant improvements that benefit both everyday users and developers, enhancing performance, readability, and flexibility in Ruby applications.

How Enhancements Introduced in the Ruby 3.4 Impact Business Value

Released Ruby 3.4 builds upon innovations like YJIT and introduces several new features and optimizations that have a profound business impact. Here’s a breakdown of how these changes affect performance, scalability, cost, and developer productivity.

Performance gains in Ruby 3.4  - Ruby 3.4 outperforms other stable versions

Ruby 3.4 incorporates YJIT enhancements, optimizations in JSON.parse, and improved parsing with the Prism parser.

What contributed to Ruby 3.4 performance gains

YJIT improvements

New memory management options (e.g., `--yjit-mem-size`) reduce the memory overhead of JIT compilation while maintaining performance gains. Inline method calls and better register allocation further enhance execution speed.

 

Faster parsing

The Prism parser accelerates Ruby's code execution by improving Ruby's efficiency in interpreting source code. Prism is now the default parser for Ruby.

Faster JSON.parse

JSON parsing is now 1.5x faster, directly benefiting applications that handle large JSON payloads, such as APIs and web services.

Additional business impact related to performance gains of Ruby 3.4 programming language

Enhanced user experience

Faster responses in web applications reduce latency and improve user satisfaction, which is critical for customer retention.

 

Cost savings

Performance gains lower CPU usage, allowing businesses to serve more users without increasing infrastructure spending.

 

Better scalability

Applications can handle increased loads, reducing the need for immediate scaling when traffic spikes.

Scalability and stability 

The modular garbage collector and changes like frozen string literals contribute to more stable and scalable applications.

What changes made by the core team in Ruby 3.4 contribute to better scalability and stability

Garbage Collection improvements

Modular GC lets developers use alternative garbage collection strategies tailored to their application needs, reducing memory leaks and ensuring stability.

Frozen string literals

Strings will be immutable by default (in other words: frozen by default in Ruby), minimizing unintentional mutations and improving memory efficiency. Current version 3.4.1 requires a `frozen_string_literal` declaration to avoid deprecation warnings if the environment has enabled deprecation warnings. 

It's a first step towards string literals frozen by default. The next steps will include raising deprecation warnings (regardless of verbosity levels) and making string literals frozen by default (proposed currently for the Ruby 4.0 version).

Additional business impact related to the scalability and stability of Ruby 3.4

Higher reliability

Memory leaks and crashes are less likely, ensuring that applications remain stable even under heavy workloads.

Seamless growth

Efficient memory management and optimized resource usage mean businesses can scale applications without immediate infrastructure upgrades.

Reduced downtime

Stability improvements lead to fewer outages, minimizing revenue losses caused by downtime.

Reduced maintenance costs

Improvements in Ruby 3.4 simplify code maintenance and long-term updates.

What contributes to Ruby 3.4 reduced maintenance costs

Consistent syntax and behavior

Updates to `Hash#inspect`, `Range#size`, and error messages ensure predictable behavior across the codebase.

Future-proof applications

Features like modular GC and Prism parsing prepare applications to adapt to future Ruby versions with minimal effort. 

The additional business value of Ruby 3.4 streamlined maintenance

Lower maintenance overheads

Predictable behavior reduces the time spent troubleshooting or rewriting code for compatibility.

Long-term savings

Applications built on Ruby 3.4 are better positioned to integrate upcoming language improvements, reducing the costs of future upgrades.

Unmatched cost efficiency of development and infrastructure

Every improvement in Ruby 3.4 contributes to better resource utilization in CPU cycles, memory usage, or developer hours.

Lower costs of web development and other Ruby 3.4 development

Optimized workloads

Features like faster JSON parsing, modular GC, and YJIT make applications more efficient in handling intensive tasks.

Efficient memory usage

By freezing strings and providing unified YJIT memory controls, Ruby 3.4 ensures better use of system resources.

Other aspects of Ruby 3.4 resulting in further cost efficiency

Lower operational costs

Businesses can achieve the same or better performance with fewer resources, reducing cloud and infrastructure expenses.

Budget-friendly scaling

Efficient code execution postpones the need for hardware upgrades or additional servers, saving capital expenses.

The Short-Term and Long-Term Business Value of Ruby 3.4

Ruby 3.4 reinforces Ruby's position as a developer-friendly language while addressing critical business needs for performance, scalability, cost efficiency, and security.

The main results of upgrading projects to Ruby 3.4:

  • Higher ROI on infrastructure investments.
  • Faster time-to-market for products.
  • Greater stability and reliability in production.

By adopting Ruby 3.4, organizations can build applications that are not only faster and more secure but also more cost-effective and future-ready. It’s a valuable step forward for businesses relying on Ruby for mission-critical applications.

Upgrade your project to Ruby 3.4

Considering an upgrade? If you're running a Rails app or any performance-sensitive Ruby application, investing in an upgrade to Ruby 3.4 is recommended.

Start by outlining dependencies and checking deprecation warnings and code quality issues. Then, clean up any code that needs attention and upgrade the Ruby version. Be sure to test the result on a staging environment to confirm the performance and stability of the solution.

For almost all projects, the benefits will significantly outweigh the upgrade effort, especially if done by Ruby development experts like iRonin.IT team - a top Ruby on Rails software development company.  Let us know if you need top Ruby developers to help with the upgrade.

Read Similar Articles