Ruby 3 is released - The list of Ruby 3 features (2024)

For all Rubyists,2020 was a special year.Why wouldn't it be?Ruby 2 was released in 2013.We have been using Ruby 2.xfor almost 7 yearsandwe have been waiting to seeRuby 3 get released.Finally,the wait is over now.Ruby 3.0.0 has been released.It's time to unwrap the gift boxand see all the Ruby 3 features we got.

Ruby 3 major updates

The number 3 is very significantin the Ruby 3 release.Be it release version number,making performance 3x faster,or the trio of core contributors(Matz, TenderLove, Koichi).Similarly, there were 3 major goals of Ruby 3: being faster,having better concurrency,andensuring correctness.

Ruby 3 is released - The list of Ruby 3 features (1)

1. Ruby 3 performance

One of the major focuses for Ruby 3was the performance.In fact,the initial discussion for Ruby 3was started around it.Matz had set a very ambitious goalof making Ruby 3 times faster.

What is Ruby 3x3?

Before discussing this,let's revisit Ruby's core philosophy.

"I hope to see Ruby help every programmer in the world to be productive, and to enjoy programming, and to be happy." - Matz

About Ruby 3x3,some askedwhether the goal was to make Ruby the fastest language?The answer is no.The main goal of Ruby 3x3 wasto make Ruby 3 times faster than Ruby 2.

“No language is fast enough.” - Matz

Ruby was not designed to be fastestandif it would have been the goal,Ruby wouldn't be the same as it is today.As Ruby language gets performance boost,it definitely helpsour application be faster and scalable.

"In the design of the Ruby language we have been primarily focused on productivity and the joy of programming. As a result, Ruby was too slow." - Matz

There are two areaswhere performance can be measured:memory and CPU.

CPU optimization

Some enhancements in Ruby internalshave been made to improve the speed.The Ruby team has optimizedthe JIT(Just In Time) compilerfrom previous versions.Ruby MJIT compilerwas first introduced in Ruby 2.6.Ruby 3 MJIT comes with better securityandseems to improve web apps’ performanceto a greater extent.

Ruby 3 is released - The list of Ruby 3 features (2)

MJIT implementation is differentfrom the usual JIT.When methods get called repeatedlye.g. 10000 times,MJIT will pick such methods which can be compiledinto native codeandput them into a queue.Later MJIT will fetch the queueandconvert them to native code.

Please checkJIT vs MJITfor more details.

Memory optimization

Ruby 3 comes with an enhanced garbage collector. It has python's buffer-like APIwhich helps in better memory utilization.Since Ruby 1.8,Ruby has continuously evolved inGarbage collectionalgorithms.

Automatic Garbage Compaction

The latest change in garbage collectionisGarbage Compaction.It was introduced in Ruby 2.7where the process was a bit manual.But in version 3 it is fully automatic.The compactor is invoked aptlyto make sure proper memory utilization.

Objects Grouping

The garbage compactor moves objects in the heap.It groups dispersed objects togetherat a single place in the memoryso that this memory can be usedeven by heavier objects later.

Ruby 3 is released - The list of Ruby 3 features (3)

2. Parallelism and Concurrency in Ruby 3

Concurrency is one of the important aspectsof any programming language.Matz feels thatThreads are not the right level of abstraction for Ruby programmers to use.

“I regret adding Threads.” - Matz

Ruby 3 makes it a lot easierto make applicationswhere concurrency is a major focus.There are several featuresandimprovements added in Ruby 3 related to concurrency.

Fibers

Fibers are considereda disruptive addition in Ruby 3.Fibers are light-weight workerswhich appear like Threadsbut have some advantages.It consumes less memory than Threads.It gives greater control to the programmerto define code segmentsthat can be paused or resumedresulting inbetter I/O handling.

Falcon Rack web serveruses Async Fibers internally.This allows Falcon to not block on I/O.Asynchronously managing I/Ogives a great upliftto the Falcon server to serve requests concurrently.

Fiber Scheduler

Fiber Scheduleris an experimental featureadded in Ruby 3.It was introducedto intercept blocking operations such as I/O.The best thing is thatit allows lightweight concurrencyandcan easily integrate into the existing codebase without changing the original logic.It's an interfaceandthat can be implemented by creating a wrapperfor a gem like EventMachine or Async.This interface design allowsseparation of concerns betweenthe event loop implementationandthe application code.

Following is an example to send multiple HTTP requests concurrently using Async.

1require 'async'2require 'net/http'3require 'uri'45LINKS = [6 'https://bigbinary.com',7 'https://basecamp.com'8]910Async do11 LINKS.each do |link|12 Async do13 Net::HTTP.get(URI(link))14 end15 end16end

Please checkfibersfor more details.

Ractors (Guilds)

As we know Ruby’s global VM lock (GVL) prevents most Ruby Threadsfrom computing in parallel.Ractorswork around the GVLto offer better parallelism.Ractor is an Actor-Model like concurrent abstraction designedto provide a parallel executionwithout thread-safety concerns.

Ractors allows Threads in different Ractorsto compute at the same time.Each Ractor has at least one thread,which may contain multiple fibers.In a Ractor,only a single thread is allowedto execute at a given time.

The following program returns the square root of a really large number. It calculates the result for both numbers in parallel.

1# Math.sqrt(number) in ractor1, ractor2 run in parallel23ractor1, ractor2 = *(1..2).map do4 Ractor.new do5 number = Ractor.recv6 Math.sqrt(number)7 end8end910# send parameters11ractor1.send 3**7112ractor2.send 4**511314p ractor1.take #=> 8.665717809264115e+1615p ractor2.take #=> 2.251799813685248e+15

3. Static Analysis

We need tests to ensure correctness of our program.However by its very nature tests could mean code duplication.

“I hate tests because they aren't DRY.” - Matz

To ensure the correctness of a program,static analysis can be a great toolin addition to tests.

The static analysis relies oninline type annotationswhich aren't DRY.The solutionto address this challengeis having .rbs files parallelto our .rb files.

RBS

RBS is a languageto describe the structure of a Ruby program.It provides us an overview of the programandhow overall classes, methods, etc.are defined.Using RBS,we can write the definition of Ruby classes, modules, methods, instance variables, variable types,andinheritance.It supports commonly used patterns in Ruby code, and advanced types like unionsandduck typing.

The .rbs files aresomething similar to .d.ts files in TypeScript.Following is a small exampleof how a .rbs file looks like.The advantage of having a type definition isthat it can be validated against both implementationandexecution.

The below example is pretty self-explanatory.One thing we can note here though, each_post accepts a block or returns an enumerator.

1# user.rbs23class User4 attr_reader name: String5 attr_reader email: String6 attr_reader age: Integer7 attr_reader posts: Array[Post]89 def initialize: (name: String,10 email: String,11 age: Integer) -> void1213 def each_post: () { (Post) -> void } -> void14 | () -> Enumerator[Post, void]15end

Please checkRBS gem documentationfor more details.

Typeprof

Introducing type definition was a challengebecause there is alreadya lot of existing Ruby code aroundandwe need a tool that could automatically generate the type signature.Typeprof is a type analysis toolthat reads plain Ruby codeandgenerates a prototype of type signature in RBS format by analyzing the methods,andits usage.Typeprof is an experimental feature.Right now only small subset of ruby is supported.

“Ruby is simple in appearance, but is very complex inside, just like our human body.” - Matz

Let's see an example.

1# user.rb2class User34 def initialize(name:, email:, age:)5 @name, @email, @age = name, email, age6 end78 attr_reader :name, :email, :age9end1011User.new(name: "John Doe", email: 'john@example.com', age: 23)

Output

1$ typeprof user.rb23# Classes4class User56 attr_reader name : String7 attr_reader email : String8 attr_reader age : Integer910 def initialize : (name: String,11 email: String,12 age: Integer) -> [String, String, Integer]1314end

Other Ruby 3 features and changes

In the 7-year period,the Ruby community has seen significant improvement in performanceandother aspects.Apart from major goals,Ruby 3 is an exciting update with lots of new features,handy syntactic changes,andnew enhancements.In this section,we will discuss some notable features.

“We are making Ruby even better.” - Matz

One-line pattern matching syntax change

Previously one-line pattern matchingused the keyword in.Now it's replaced with =>.

Ruby 2.7
1 { name: 'John', role: 'CTO' } in {name:}2 p name # => 'John'
Ruby 3.0
1 { name: 'John', role: 'CTO' } => {name:}2 p name # => 'John'

Find pattern

Thefind patternwas introduced in Ruby 2.7as an experimental feature.This is now part of Ruby 3.0.It is similar to pattern matching inElixir or Haskell.

1users = [2 { name: 'Oliver', role: 'CTO' },3 { name: 'Sam', role: 'Manager' },4 { role: 'customer' },5 { name: 'Eve', city: 'New York' },6 { name: 'Peter' },7 { city: 'Chicago' }8]910users.each do |person|11 case person12 in { name:, role: 'CTO' }13 p "#{name} is the Founder."14 in { name:, role: designation }15 p "#{name} is a #{designation}."16 in { name:, city: 'New York' }17 p "#{name} lives in New York."18 in {role: designation}19 p "Unknown is a #{designation}."20 in { name: }21 p "#{name}'s designation is unknown."22 else23 p "Pattern not found."24 end25end2627"Oliver is the Founder."28"Sam is a Manager."29"Unknown is a customer."30"Eve lives in New York."31"Peter's designation is unknown."32"Pattern not found."

Endless Method definition

This is another syntax enhancement that is optional to use.It enables us to create method definitionswithout end keyword.

1def: increment(x) = x + 123p increment(42) #=> 43

Except method in Hash

Sometimes while working on a non Rails appI get undefined method except.The except method was available only in Rails.In Ruby 3 Hash#except wasadded to Rubyitself.

1user = { name: 'Oliver', age: 29, role: 'CTO' }23user.except(:role) #=> {:name=> "Oliver", :age=> 29}

Memory View

This is again an experimental feature.This is a C-APIthat will allow extension librariesto exchange raw memory area.Extension libraries can alsoshare metadata of memory areathat consists of shapeandelement format.It was inspired byPython’s buffer protocol.

Arguments forwarding

Arguments forwarding (...)now supports leading arguments.

It is helpful in method_missing,where we need method name as well.

1def method_missing(name, ...)2 if name.to_s.end_with?('?')3 self[name]4 else5 fallback(name, ...)6 end7end

Other Notable changes

  • Pasting in IRB is much faster.
  • The order of backtrace had been reversed.The error message and line number are printed first, rest of the backtrace is printed later.
  • Hash#transform_keysaccepts a hash that maps old keys with new keys.
  • Interpolated String literals are no longer frozen when # frozen-string-literal: true is used.
  • Symbol#to_proc now returns a lambda Proc.
  • Symbol#namehas been added, which returns the symbol's name as a frozen string.

Many other changes can be checked atRuby 3 Newsfor more details.

Transition

A lot of core libraries have been modifiedto fit the Ruby 3 goal needs.But this doesn't meanthat our old applications will suddenly stop working.The Ruby team has made surethat these changes are backward compatible.We might see some deprecation warningsin our existing code.The developers can fix these warningsto smoothly transition from an old versionto the new version.We are all set to use new featuresandget all new performance improvements.

Conclusion

With great improvements in performance,memory utilization, static analysis,andnew features like Ractorsandschedulers,we have great confidencein the future of Ruby.With Ruby 3,the applications can be more scalableandmore enjoyable to work with.The coming 2021 is not just a new yearbut rather a new era for all Rubyists.We at BigBinary thank everyone who contributed towards the Ruby 3 release directly or indirectly.

Happy Holidays and Happy New Year folks!!!

Ruby 3 is released - The list of Ruby 3 features (2024)

References

Top Articles
Latest Posts
Article information

Author: Frankie Dare

Last Updated:

Views: 6571

Rating: 4.2 / 5 (73 voted)

Reviews: 80% of readers found this page helpful

Author information

Name: Frankie Dare

Birthday: 2000-01-27

Address: Suite 313 45115 Caridad Freeway, Port Barabaraville, MS 66713

Phone: +3769542039359

Job: Sales Manager

Hobby: Baton twirling, Stand-up comedy, Leather crafting, Rugby, tabletop games, Jigsaw puzzles, Air sports

Introduction: My name is Frankie Dare, I am a funny, beautiful, proud, fair, pleasant, cheerful, enthusiastic person who loves writing and wants to share my knowledge and understanding with you.