The letter A styled as Alchemists logo. lchemists
Published December 25, 2022 Updated April 18, 2023
Ruby 3.2.0

Once again, a new release of Ruby has arrived along with a host of new features over last year’s 3.1.0 release. The following is a capture of some of the highlights but definitely dig into the release notes for complete details. Enjoy!

  • YJIT: No longer experimental, is optimized for object shapes, and supports both x86-64 and arm64 architectures. 🎉 If you need additional convincing, check out the Benchmarks. Feel free to use my Docker Alpine Ruby image for experimentation as it comes with built-in YJIT support for you. 🚀

  • Variable Width Allocation (VWA): Introduced for the first time, is now default, and improves memory allocation in the virtual machine. Previously, Ruby would allocate 40 bytes for each object where some data would be stored in the remaining ~20 byte slots for book keeping purposes. The problem is that some objects would end up needing more than 40 bytes which would cause additional 40 byte slot allocations elsewhere in memory. This non-contiguous and fragmented allocation of memory was expensive to read so now, with VWA, memory is allocated in multiple sized slots to allow for bigger objects to be read more efficiently. For more on this, check out Matt Valentine’s RubyKaigi Talk.

  • Object Shapes: Knowing the shape of an object allows the virtual machine to improve performance by identifying which objects share the same set of properties such as instance variables and frozen status. See Ayush Poddar’s Article and Jemma Issroff’s Curuko Talk for further details.

  • WebAssembly (WASM): WebAssembly with WebAssembly System Interface (WASI) is here. As a quick start, you can use my article to learn how to compile and run an example Ruby program using the WASI Virtual File System (VSF). I’ll be writing more about this in the future, so stay tuned!

  • Regular Expressions: Performance has increased considerably with this release along with the ability to provide a global timeout (i.e. Rexexp.timeout = 1.0) or instance timeout (i.e."\w+", timeout: 1.0)).

  • Syntax Detection: We now have more syntax feedback via the following gems:

  • Anonymous Splat Forwarding: Much like anonymous block forwarding — added in 3.1.0 — you can now forward single and double splats. Check out my Method Parameters and Arguments article, for details, by paying special attention to the splats sections.

  • Find Pattern Matching: This feature is no longer experimental. 🎉 For complete details, check out my Pattern Matching article and pay attention to how Array finds work.

  • Enumerators: A new Enumerator.product method has been added which provide a quick way to obtain an iterable product of multiple arrays.

  • Data: A new Data primitive has been added to the language which finally gives us an immutable value object. This works like a Struct but has a much smaller footprint, improved performance, and immutable instances. Check out my Ruby Data article for details.

  • Procs: Support was added for proc parameters to convert themselves into lambda parameters. Example: my_proc.parameters lambda: true. For details, check out my Method Parameters and Arguments article by paying special attention to the Procs and Lambdas section.

  • Refinements: The following features have been added so definitely check out my Refinements article for a deeper dive:

    • Added Module#used_refinements.

    • Added Module#refinements.

    • Added Refinement#refined_class.

  • Sets: You no longer need to use require "set" to require the Set class since it is autoloaded for you.

  • Structs: A Struct can be initialized without the use of keyword_init: true. Check out my Structs article for an up-to-date and detailed breakdown.

  • Standard Libraries: A bunch of updates have been made to the Standard Libraries. Make sure to check the release notes for details.